Class with a pointer to itself

This is a discussion on Class with a pointer to itself within the C++ Programming forums, part of the General Programming Boards category; I need to make a quadtree. I have: Code: class Quadtree { public: ... private: Quadtree children[4]; ... }; I ...

  1. #1
    Registered User
    Join Date
    Nov 2005
    Posts
    137

    Class with a pointer to itself

    I need to make a quadtree.

    I have:
    Code:
    class Quadtree
    {
    public:
        ...
    private:
        Quadtree children[4];
        ...
    };
    I get an error saying: "error: field 'children' has an incomplete type"

    Can anyone tell me what is wrong?

    Thank you.

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,334
    A struct/class can't contain a copy of itself!
    Otherwise it would recursively fill memory as soon as you tried to instantiate it.

    Quadtree *children[4];
    fixes this.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    20,968
    An array is not a pointer. Here, you have a class that has an array with 4 elements of the same class. This is impossible, since your Quadtree object contains 4 Quadtree objects, each of which contains 4 Quadtree objects, each of which contains 4 Quadtree objects, etc.

    What you can do is really store a Quadtree pointer, and then have this pointer point to the first element of an array of 4 Quadtree objects.

    EDIT:
    Oh yes, storing 4 Quadtree pointers, each of which points to exactly one Quadtree object, also works.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Nov 2005
    Posts
    137
    Ok, that makes sense. I tried using Quadtree *children[4]; but I get a lot of errors.

    Why can I not do something like this:
    Code:
    Quadtree::Quadtree()
    {
        children = new Quadtree[4];
        for (int i = 0; i < 4; i++)
            children[i] = NULL;
    }
    Anywhere I treat children as an array, I get an error. How can I treat children like an array?

  5. #5
    Registered User Will Hemsworth's Avatar
    Join Date
    Sep 2008
    Location
    England - Lymm
    Posts
    6
    Try changing it to something like this.

    Code:
    class Quadtree
    {
    private:
        Quadtree *children;
    
    public:
        Quadtree() {
           children = new Quadtree[4];
        }
        ~Quadtree() {
           delete[] children;
        }
    };
    Edit: this will also cause a runtime error as it still recursively allocates Quadtree's, so Salem's method should work.
    Last edited by Will Hemsworth; 09-21-2008 at 12:11 PM.

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Wouldn't new Quadtree[4] make an array of quadtrees? Don't you want an array of pointers-to-quadtree?

  7. #7
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,334
    You already have an array of 4 pointers, so just delete this line
    children = new Quadtree[4];

    Then when you need them, it's
    Code:
    children[i] = new Quadtree;
    But you still need to watch out for calling the constructors recursively if you try to fill out a complete tree as soon as you construct it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    20,968
    Why can I not do something like this
    Because children[i] is a Quadtree, not a pointer, assuming that children is a Quadtree pointer. You have to pick either what Salem suggested or what I suggested, not both.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Isn't the real problem that you are creating the children in the constructor of the same class, which makes the constructor infinitely recursive. You can't do THAT!

    Likewise, you can't delete inside the destructor.

    At the very least you would need to make sure that the constructor and destructor have some sort of condition (if the compiler would allows this sort of thing, it would crash the program either because of out-of-memory or out-of-stack, since you'd never stop calling the constructor, and should you ever end calling the constructor, the same thing happens for the destructor calls.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User
    Join Date
    Nov 2005
    Posts
    137
    Ok, I understand. Thank you.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    20,968
    Isn't the real problem that you are creating the children in the constructor of the same class, which makes the constructor infinitely recursive. You can't do THAT!

    Likewise, you can't delete inside the destructor.
    It depends. A Quadtree object can own another (or 4 other) Quadtree objects, but eventually there must be a Quadtree object that does not own any other Quadtree object.

    With my suggestion, the Quadtree pointer can be null. With Salem's suggestion, this can be done by keeping the Quadtree pointers null, which implies that there is greater flexibility (though the placement new trick can be used with my suggestion, but that's a different story).

    yahn's most recent code looks like an attempt to use Salem's suggestion with setting the pointers to null, and that would work, except that yahn also tried using my suggestion simultaneously. Considering the definition of a Quadtree though, my suggestion is probably not as good, since a Quadtree is not fixed at 4 children or none, but fixed at up to 4 children (but in my defense, I did not know that at the time).
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Initializing a pointer in a class.
    By gpr1me in forum C++ Programming
    Replies: 3
    Last Post: 03-22-2006, 02:05 PM
  3. class passing a pointer to self to other class
    By daioyayubi in forum C++ Programming
    Replies: 3
    Last Post: 09-05-2005, 09:25 AM
  4. base class pointer problems
    By ... in forum C++ Programming
    Replies: 3
    Last Post: 11-16-2003, 10:27 PM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21