[SOLVED] C++ Accessing a protected member of the same class from a different instance

Started by
2 comments, last by Matias Goldberg 14 years, 9 months ago
Hi all! I'm using Visual C++ Express 2005 SP1. I'm having issues accessing a protected member from an up class from a different instance of the same class. Here's the scenario:

class Base
{
protected:
	int myVar;
};

class Derived : public Base
{
public:
	void oneFunc( Base *p )
	{
		p->myVar = 0;                             //Error
		(static_cast<Derived*>(p))->myVar = 0;    //OK
	}

	void twoFunc( Derived *p )
	{
		p->myVar = 0;                             //OK
	}
};

"twoFunc" is compiled propperly. However, "oneFunc" does not. If I downcast, it works. If I don't downcast, it throws me a compile error.
Quote:main.cpp(65) : error C2248: 'Base::myVar' : cannot access protected member declared in class 'Base' main.cpp(57) : see declaration of 'Base::myVar' main.cpp(55) : see declaration of 'Base'
Last time I check, I should be able to compile that code, and I shouldn't need to downcast because the memory address should remain the same, but since the compiler is telling me this is wrong: a) Is this a compiler bug? (highly unlikely, like always) b) Am I missing a specific scenario which makes the downcast unsafe? (my main concern) The only scenario I can think of is that Derived has also a variable with the same name (in this case, myVar) in which case Derived::myVar and Base::myVar would point to different memory addresses and the compiler wouldn't know which one I'm referring to (and making a downcast unsafe). Am I missing something else? Shouldn't this be a compiler warning rather an error? I don't like leaving loose ends in my code (with downcastings!) making my code potentially unsafe. Can anyone enligthen me a bit, please? Thanks Dark Sylinc [Edited by - Matias Goldberg on August 8, 2009 1:16:33 PM]
Advertisement
The formal way to address variable in inherited class is:
Base::myVar = 0;// orthis->myVar;


GCC requires this for templated classes, MVC never requires it (which is incorrect).

Obviously, when you are passed an instance, you can only access its public members, or members you declared. In this case, the members declared by Derived - but not base.

I have no clue why this is required, but there's probably an arcane special case with multiple inheritance or some scope resolution or whatnot.

A Foo can only access public members of any other type, and all members declared by Foo, regardless of inheritance.


Either way, I personally never encountered this problem before, or had the need for such access. Are you sure you need this?
The compiler is right. The relevant section of the standard is 11.5 paragraph 1:
Quote:C++ Standard (ISO/IEC 14882:2003): Section 11.5, Paragraph 1 (excerpt)

"When a friend or a member function of a derived class references a protected nonstatic member function or protected nonstatic data member of a base class, an access check applies in addition to those described earlier in clause 11. Except when forming a pointer to member (5.3.1), the access must be through a pointer to, reference to, or object of the derived class itself (or any class derived from that class) (5.2.5). If the access is to form a pointer to member, the nested-name-specifier shall name the derived class (or any class derived from that class)."
@Metsan:
Really Thanks.

Quote:Original post by Antheus
Either way, I personally never encountered this problem before, or had the need for such access. Are you sure you need this?

Like everyone who just gets with a problem, I was sure I *needed* it.
This actually happened because my project programming leader wanted me to change some of my code and get it integrated with his code.

I've just found a quick way to fix it (dumber than it looks):
inline int getMyVar() { return myVar; }


Hopefully it will get inlined, I don't have to worry about scopes or castings, and I can make it virtual if I ever wanted to return two different variables with the same name (although making it virtual seems overkill, besides I'm pretty sure I won't need it)

Thanks to all
Cheers
Dark Sylinc

This topic is closed to new replies.

Advertisement