0

Okay, so I am having some troubles in creating a Parent/Child relationship. The easiest way I can explain this is having an object, with a reference (or pointer) to another object of the same type, and then an array of children references (or pointers) to more objects. The object should have functions like .getChildren, .addChild, .removeChild, .getParent, .changeParent. I'm having a horrible time with the pointers, and if anyone could help with the code that'd be great. Also, in case anyone is curious, I'm going to use this approach with 3D models. The base model (parent) will be the center of the object, all children can move freely, and when the parents moves, it causes the children to move.

Code:

class Base {
  protected:
    Base* parent;
    std::vector<Base*> children;

    std::string id;

    POINT pos, rot;
  public:
    Base (void);
    Base (std::string);
    Base (POINT, POINT, std::string);
    Base (const Base&);
    ~Base (void);

    POINT getPos (void);
    POINT getRot (void);

    Base getParent (void);
    Base getChildren (void);

    void addChild (Base&);
    void removeChild (Base&);
    void changeParent (Base);

    void move (int, int);
    void rotate (int, int);

    void collide (Base);
    void render (void);
};

Base::Base (void) {
    this->id = getRandomId();
    this->pos.x = 0; this->pos.y = 0; this->pos.z = 0;
    this->rot.x = 0; this->rot.y = 0; this->rot.z = 0;
};

Base::Base (std::string str) {
    this->id = str;
    this->pos.x = 0; this->pos.y = 0; this->pos.z = 0;
    this->rot.x = 0; this->rot.y = 0; this->rot.z = 0;
};

Base::Base (POINT p, POINT r, std::string str) {
    this->id = str;
    this->pos = p;
    this->rot = r;
};

Base::Base (const Base& tocopy) {
    this->parent = tocopy.parent;
    this->children = tocopy.children;
    this->id = tocopy.id;
    this->pos = tocopy.pos;
    this->rot = tocopy.rot;
};

Base::~Base (void) {
};

void Base::changeParent (Base child) {
    *(this->parent) = child;
};

int main (void) {
    POINT p;
    p.x=0;p.y=0;p.z=3;
    Base A;
    Base B(p, p, "Unique");
    printf("A.pos.z is %d and B.pos.z is %d\n", A.getPos().z, B.getPos().z);
    B.changeParent(A);
    printf("B.parent.pos.z %d should equal 0\n", B.parent->getPos().z);

The error I get with the code is: error C2248: 'Base::parent' : cannot access protected member declared in class 'Base' Also, if I make everything public, it'll compile fine, but then it crashes on run.

Note: I didn't copy all of the code, just what I thought would be relevant.

EDIT: Full dump of the error:

(152) : error C2248: 'Base::parent' : cannot access protected member declared in class 'Base'
    (20) : see declaration of 'Base::parent'
    (18) : see declaration of 'Base'
Polosky
  • 88
  • 5
  • 13
  • the line where the error is coming from would help. Also, you should use [initialization lists](http://www.cprogramming.com/tutorial/initialization-lists-c++.html) for your constructors instead of all the this-> stuff, it'll save a copy. – Paul Rubel Sep 20 '11 at 22:39
  • Edited post with the dump. I don't quite understand those, I just read about those not too long ago, so I'm not worried about it just yet. – Polosky Sep 20 '11 at 22:42
  • Also, I don't really think I'm doing something wrong, language wise, since it will compile if I change "protected" to "public" but just crash on runtime. – Polosky Sep 20 '11 at 22:43
  • `changeParent` takes a 'child' as an argument to be the new parent? How confusing! – K-ballo Sep 20 '11 at 22:48
  • I would advise you to use smart pointers in your code, ensuring you also use an appropriate container for them, otherwise you may end up with memory leaks when deleting your graph of objects. – Tony Sep 20 '11 at 22:49
  • Ugh -_- so many typos. I think I'm going to scrap this whole thing and start over. – Polosky Sep 20 '11 at 22:49
  • @Tony, what exactly is a smart pointer? – Polosky Sep 20 '11 at 22:50
  • @Hondros - Rather than me trying to explain have a read of http://ootips.org/yonat/4dev/smart-pointers.html or just search for "smart pointers". Be aware that using `std` containers with smart pointers can have problems: http://stackoverflow.com/questions/4577838/smart-pointers-in-container-like-stdvector – Tony Sep 20 '11 at 22:54
  • @Tony thank you for links. I probably should've googled that. I'm just going to scrap this code and rewrite it for now. Thanks :D – Polosky Sep 20 '11 at 22:55

2 Answers2

0

This

printf("B.parent.pos.z %d should equal 0\n", B.parent->getPos()

raises your error because of this

protected:
  Base* parent;

You're trying to reference B.parent from outside of the class implementation. Because parent is declared protected it isn't available there. In your declaration of Base, you should add an accessor function that returns parent and is public, like:

public:
  inline Base* getParent() { return parent; }
adpalumbo
  • 3,031
  • 12
  • 12
  • You know what's funny. I actually had this defined in my code, and I had forgotten to use. Thanks. EDIT: Unfortunately, it's still crashing on start. So, thanks for solving one issue, but what should i do now? – Polosky Sep 20 '11 at 22:47
  • No offense, but your use of pointers is messy and likely to have you running into crashes and unexpected behavior for a while. It's hard to analyze all of the issues here. However, the next most immediate problem is at `*(this->parent) = child` in `changeParent`. Here, you dereference a pointer (`parent`) that was never initialized, and then assign something to it, which is almost always going to cause a crash. Minimally, you want `this->parent = &child` here, but a thorough review of your code would be even better. – adpalumbo Sep 20 '11 at 22:56
0

It always helps if you tell us which line has the error. If you'd mentioned it was this line, you'd have 10 answers by now.

printf("B.parent.pos.z %d should equal 0\n", B.parent->getPos().z);

int main() cannot access protected members of Base, and thus cannot access B.parent. Replace this with:

printf("B.getParent().pos.z %d should equal 0\n", B.getParent()->getPos().z);

http://ideone.com/CobdS Also note that getParent() should probably return a pointer (Base*), and getChildren() should probably return const std::vector<Base*>&

Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
  • If you look at the edit, it shows the line, and I already have the answer. Thank you though. Also, this doesn't solve my runtime error, but I am just scrapping this code. – Polosky Sep 20 '11 at 22:56
  • Yeah, do that. Moving points in this manner is actually quite slow unfortunately. – Mooing Duck Sep 20 '11 at 22:58