views:

104

answers:

1

Following up on this question, people have suggested I go with "option 3" which might look like this:

class b2Body {
private:
 b2Body() {}
 friend class b2World;
};

class Body : public b2Body {
private:
 Body() {}
 friend class World;
};

class b2World {
public:
 b2Body *CreateBody() {
  return new b2Body;
 }
};

class World : public b2World {
public:
 Body *CreateBody() {
  return new Body;
 }
};

int main() {
 World w;
 Body *b = w.CreateBody();
 return 0;
}

Try it online

But there are two major problems with this:

  1. Body can never be constructed, even with World::CreateBody (because b2Body is private)
  2. Even if it could, then the b2Body part wouldn't be initialized correctly (b2World::CreateBody needs to be called)

Does this mean I can never inherit from b2Body/b2World and follow this same design pattern? (keep in mind that I can't edit the b2* classes)

If so, I suppose you guys would recommend I just keep b2World and b2Body as member variables instead?


I think it comes down to these two options now:

+2  A: 

Only b2World can create a b2Body so this just doesn't go anywhere. These classes clearly aren't designed to be inherited from so yes, aggregate them instead. What about something along the lines of

class Body {
public:
    Body( b2Body* b ) : b2b( b ) {}

private:
    b2Body*const b2b;
};

class World {
public:
    World() : b2w( /* create b2w here */ ) {}

    Body *CreateBody() {
            return new Body( b2w->CreateBody( /*...*/ ); }
    }
private:
    b2World*const b2w;
};
Troubadour
Nice! Then `Body` doesn't need to friend `World`. http://codepad.org/CXufhOiY
Mark