Sign in to follow this  
DaJudge

C++ inheritance weirdness

Recommended Posts

Hi all, I am just totally confused by my compiler (MSVC++ .NET 2003). I just don't know if I'm simply being stupid now or if my compiler just spits out garbage. I do C++ for some years now so I'd expect myself to know a bit about inheritance... Here the problem:
class Geom : public RefCount
{
...
protected:
	/// Notifies this geom that it's now the child of another geom
	virtual void AttachNotify(const Vector3& relative_pos, const D3DXQUATERNION& relative_rotation)=0;
protected:
	/// Notifies this geom that it just got detached from its parent
	virtual void DetachNotify()=0;
...
}

class GeomTranslate : public Geom
{
...
}

GeomTranslate::GeomTranslate(... Geom* child, ...)
{

...
	// This code actually is the one I want
	child->AttachNotify(...);

	// This is the one I just added for verifying
	((Geom*)this)->AttachNotify(...);
...
};
My understanding of inheritance tells me that both calls to AttachNotify() should work perfectly as expected. However, the compiler tells me both times: error C2248: 'Geom::AttachNotify' : cannot access protected member declared in class 'Geom' Please someone tell me I'm not entirely stupid. Cheers, Alex

Share this post


Link to post
Share on other sites
Well its a pure virtual function. There's nothing to call. You need to define it first. I'm surprised the compiler would even letyou try to instatiate your class.

You shouldn't be able to create classes with pure virtual methods.

Cheers
Chris

Share this post


Link to post
Share on other sites
Sorry, forgot to include the function definition of GeomTranslate::AttachNotify(). It's there indeed:



class GeomTranslate : public Geom
{
...
protected:
/// Notifies this geom that it's now the child of another geom
virtual void AttachNotify(const Vector3& relative_pos, const D3DXQUATERNION& relative_rotation);
protected:
/// Notifies this geom that it just got detached from its parent
virtual void DetachNotify();
...
}

Share this post


Link to post
Share on other sites
Well for the first call you can't call the a geom's appendchild method because you don't have access rights to it. That class can only do it for itself, not for other types of the same class.

Hope that helps

Cheers
Chris

Share this post


Link to post
Share on other sites
GeomTranslate inherit Geom, but that does not make instances of GeomTranslate to access protected (or private) members of other instances of Geom. You can access the protected ones in your own instance but not in other instances.

EDIT: Damn, chollida1 beat me by a couple of seconds... ;)

Share this post


Link to post
Share on other sites
Interesting one. I didn't know the answer to this myself so I googled and found this.

It says that according to the standard access to a protected member may only be made through an object or pointer- or reference-to the derived class. So if you passed in a GeomTranslate pointer, reference or object you'd be OK, but accessing it from a Geom pointer is not allowed.

Just to make clear - the above two posters are wrong. If the class has access rights then it can use those access rights for any instance of its own class, not just its own instance. I was suprised when I first learned this, but it can be useful.

Having made the above assertion I'm going to retract it again since I can't actually think of a way to test it at the moment and I am becoming less certain of its accuracy.

And just to see how many times I can edit this post before getting an edit timestamp I just thought of a way to test it and am able to make the assertion again:

Just to make clear - the above two posters are wrong. If the class has access rights then it can use those access rights for any instance of its own class, not just its own instance. I was suprised when I first learned this, but it can be useful.

class Base
{
};

class Mid
:
public Base
{

protected:

void function();

};

void Mid::function()
{
}

class Derived
:
public Mid
{

public:

Derived();
Derived(Derived* m);

};

Derived::Derived()
{
}

Derived::Derived(Derived* m)
{
m->function();
}

int main()
{
Derived d;
Derived d2(&d);
}


Enigma

Share this post


Link to post
Share on other sites
Quote:
Original post by DaJudge
So I am actually _forced_ to make it public in order to use it the way I want to?


You don't have to, you could do a forward class declaration of GeomTranslate and then make it a friend of Geom e.g.


class GeomTranslate;

class Geom {

friend class GeomTranslate; //now GeomTranslate has access
//....
};

class GeomTranslate : public Geom {
//...
};

Share this post


Link to post
Share on other sites
The question is:

what is the less hacky version... Delegation to the base class or the friend thing. Assuming that Geom is just a interface for an unknown number of subclasses I guess delegation is the way to go...

Your opinion?

Cheers,
Alex

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this