Skip to main content
GameDev.net gamedev.net
🔒 Locked

C++: protected

Started by Evil Steve Nov 13, 2009 at 5:40 AM 10 replies 3k views
Original Post
Evil Steve
Evil Steve
I thought I knew this stuff, but apparently I don't... I have the following code, which doesn't compile:

class Base
{
protected:
	void foo() {}
};

class Derived : public Base
{
public:
	void Bar()
	{
		Base x;
		x.foo();
	}
};

int main(int argc, char** argv))
{
	Derived a;
	a.Bar();
	return 0;
}

It gives the compile error "error C2248: 'Base::foo' : cannot access protected member declared in class 'Base'". Why is that? I thought that protected meant "This can be accessed by instances of this class, or its derived classes", but it seems to not be the case if I try to access foo() from a different instance of a derived class. This seems "wrong" to me (Although I'm sure it's not), since if I change x to a Derived, it compiles fine. I don't really see why it should make a difference, since the call to foo() is still coming from the same object type... So, what is the "correct" definition of protected?
Wan
Wan
Unless I'm wrong: foo is protected, so you can't call it like it's public. The fact that you call within a derived class instance should be irrelevant.
Codeka
Codeka
Consider this:

class A{protected:  void foo();};class B : public A{};class C : public A{public:  void bar(A &a)  {    a.foo();  }};void main{  // if what you were asking were legal, this would be possible:  C c;  B b;  c.bar(b);}
dave
dave
For reference, check the standard, section 11.5.
Evil Steve
Evil Steve
Quote:
Original post by Wan
Unless I'm wrong: foo is protected, so you can't call it like it's public. The fact that you call within a derived class instance should be irrelevant.
But foo() is being called from a derived class, why shouldn't the derived class be allowed to call a protected function in the base class?

Quote:
Original post by Codeka
Consider this:

*** Source Snippet Removed ***
I don't see the problem with that? You're accessing a protected function of A from a class derived from A. Both B and C are derived from A, so should be allowed to access the protected members?

Quote:
Original post by Dave
For reference, check the standard, section 11.5.
I had a look at that actually; the pb->i = 1; // ill-formed line is the same issue here, but I don't understand why it's ill-formed?
Wan
Wan
Quote:
Original post by Evil Steve
Quote:
Original post by Wan
Unless I'm wrong: foo is protected, so you can't call it like it's public. The fact that you call within a derived class instance should be irrelevant.
But foo() is being called from a derived class, why shouldn't the derived class be allowed to call a protected function in the base class?

Because in this case you're calling foo of an instance of base.
I think you're confused with this:

class Derived : public Base{public:	void Bar()	{		/*		Base x;		x.foo();		*/		foo();	}};
Rattrap
Rattrap
I think you would have to make Derived a friend of Base to make the code work as you've got it now.
"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]
Evil Steve
Evil Steve
So "protected" only grants access to this instance's derived classes, and grants access to any instance of this class type?

EDIT: reworded slightly

[Edited by - Evil Steve on November 13, 2009 7:02:32 AM]
SiCrane
SiCrane
It's more that a derived class, D, can only access protected members of a base class if the concrete type of the instance it's accessing is known to be a D or one of D's children.
Evil Steve
Evil Steve
Quote:
Original post by SiCrane
It's more that a derived class, D, can only access protected members of a base class if the concrete type of the instance it's accessing is known to be a D or one of D's children.
Ahh, that makes sense. Thanks!
DevFred
DevFred
Quote:
Original post by Evil Steve
I thought I knew this stuff

It takes forever to know all of C++. And when you finally know all of C++, the committee publishes a new standard that is twice as large as the old one ;)
frob
frob
The description of protected is short, but it has lots of little details.



Protected means "its name can be used only by members and friends of the class in which it is declared, and by members and friends of classes derived from this class". "When a friend or a member function of a derived class references a protected nonstatic 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)."



I added emphasis to the key words you were missing.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.