C++ 为什么派生类不能在这段代码中调用受保护的成员函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16785069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can't a derived class call protected member function in this code?
提问by Martin Drozdik
#include <iostream>
class Base
{
protected:
void somethingProtected()
{
std::cout << "lala" << std::endl;
}
};
class Derived : public Base
{
public:
void somethingDerived()
{
Base b;
b.somethingProtected(); // This does not compile
somethingProtected(); // But this is fine
}
};
int main()
{
Derived d;
d.somethingDerived();
return 0;
}
I thought that maybe only the protected members of this
can be used and protected members of other instances are forever unreachable.
我想也许只有 的受保护成员this
可以使用,而其他实例的受保护成员永远无法访问。
But:
但:
class Derived : public Base
{
public:
void somethingDerived(Derived& d)
{
d.somethingProtected(); // This compiles even though d is
// potentially a different instance
}
void somethingDerived(Base& b)
{
b.somethingProtected(); // This does not
}
};
I feel kind of nauseated by this, since I have been programming in C++ for some time, but I could not find any explanation for this behaviour.
我对此感到有点恶心,因为我已经用 C++ 编程了一段时间,但我找不到对这种行为的任何解释。
EDIT:
编辑:
It doesn't matter if it is the same or a different instance:
它是相同的还是不同的实例并不重要:
int main()
{
Derived d1, d2; // Two different instances
d1.somethingDerived(d2); // This compiles fine
d1.somethingDerived(d1); // This compiles fine
return 0;
}
EDIT2:
编辑2:
It seems that when it comes to access rights, it doesn't matter at all what instanceof a class is being used:
似乎在访问权限方面,使用类的哪个实例根本无关紧要:
class Base
{
public:
void something(Base& b) // Another instance
{
++b.a; // But can enter private members
}
private:
int a;
};
回答by AnT
Even though access control in C++ works on per-class basis (as opposed to per-instance basis), protected
access specifier has some peculiarities.
尽管 C++ 中的访问控制是基于每个类(而不是基于每个实例)进行的,但protected
访问说明符有一些特殊性。
The language specification wants to ensure that you are accessing a protected member of some base subobjectthat belongs to the derived class. You are not supposed to be able access protected members of some unrelated independent objects of base type. In particular, you cannot access protected members of freestandingobjects of base type. You are only allowed to access protected members of base objects that are embeddedinto derived objects as base subobjects.
语言规范希望确保您正在访问属于派生类的某个基子对象的受保护成员。您不应该能够访问基本类型的一些不相关的独立对象的受保护成员。特别是,您不能访问基类型的独立对象的受保护成员。您只能访问作为基础子对象嵌入派生对象的基础对象的受保护成员。
For this reason, you have to access protected members through pointer->member
syntax, reference.member
or object.member
syntax, where the pointer/reference/object refers to the derivedclass.
因此,您必须通过pointer->member
语法reference.member
或object.member
语法访问受保护的成员,其中指针/引用/对象是指派生类。
This means that in your example, protected member somethingProtected()
is not accessible through Base
objects, Base *
pointers or Base &
references, but it is accessible through Derived
objects, Derived *
pointers and Derived &
references. Your plain somethingProtected()
access is allowed, since it is just a shorthand for this->somethingProtected()
where this
is of type Derived *
.
这意味着在您的示例中,somethingProtected()
不能通过Base
对象、Base *
指针或Base &
引用访问受保护成员,但可以通过Derived
对象、Derived *
指针和Derived &
引用访问它。somethingProtected()
允许您进行简单访问,因为它只是this->somethingProtected()
wherethis
类型的简写Derived *
。
b.somethingProtected()
violates the above requirements.
b.somethingProtected()
违反了上述要求。
Note that in accordance with the above rules in
注意按照上面的规则在
void Derived::somethingDerived()
{
Base *b = this;
b->somethingProtected(); // ERROR
this->somethingProtected(); // OK
}
the first call will also fail while the second one will compile, even though both are trying to access the same entity.
第一个调用也会失败,而第二个调用会编译,即使两者都试图访问同一个实体。
回答by Dory Zidon
I believe you have some confusion on how to access base class members. It is only this way:
我相信您对如何访问基类成员有些困惑。只有这样:
class Derived : public Base
void drivedMethod() {
Base::baseMethod();
}
in your example you are trying to access a protected member of another instance.
在您的示例中,您正在尝试访问另一个实例的受保护成员。
a Derived instance will have access to it's own protected members but not to another class instance protected members, this is by design.
派生实例将有权访问它自己的受保护成员,但不能访问另一个类实例受保护成员,这是设计使然。
In fact accessing the protected members of another class, from another instance members or from the main function are in fact both under public access...
实际上,从另一个实例成员或从主函数访问另一个类的受保护成员实际上都在公共访问之下......
http://www.cplusplus.com/doc/tutorial/inheritance/(look for the access specifier table to see the different levels)
http://www.cplusplus.com/doc/tutorial/inheritance/(查找访问说明符表以查看不同级别)
Both examples prove the same thing for example:
两个例子都证明了同样的事情,例如:
void somethingDerived(Base& b)
{
b.somethingProtected(); // This does not
here your Derived class is getting b as a parameter, so it is getting another instance of base, then because b.somethingProtected is not public it will not complie..
在这里,您的派生类将 b 作为参数,因此它正在获取 base 的另一个实例,然后因为 b.somethingProtected 不是公共的,所以它不会符合 ..
this will complie:
这将符合:
void somethingDerived()
{
Base::somethingDerived();
your second example complies fine because you are accessing a public method on another d class
您的第二个示例符合要求,因为您正在访问另一个 d 类上的公共方法
> void somethingDerived(Base& b)
> {
> b.somethingProtected(); // This does not
> }
回答by Chris Dodd
The Derived
class can only access the protected base member in Derived
objects. It cannot access the member in objects that are not (necessarily) Derived
objects. In the cases that fail, you are trying to access the member via a Base &
, and since this might refer to an object that is not Derived
, the access can't be made.
本Derived
类只能访问受保护的基本部件Derived
的对象。它不能访问不是(必然)Derived
对象的对象中的成员。在失败的情况下,您尝试通过 访问成员Base &
,并且由于这可能引用不是 的对象,因此无法Derived
进行访问。
回答by Deepu
What you have done is illegal in C++. A protected member can not be accessed by an object of a class. Only member functions can access protected members. protected
members behave just like private members except while inherited by a derived class. Consider the program given below to understand the difference between private, public and protected members.
你所做的在 C++ 中是非法的。受保护的成员不能被类的对象访问。只有成员函数可以访问受保护的成员。protected
成员的行为就像私有成员一样,除非被派生类继承。考虑下面给出的程序以了解私有成员、公共成员和受保护成员之间的区别。
class Base
{
private:
void somethingPrivate()
{
std::cout << "sasa" << std::endl;
}
public:
void somethingPublic()
{
std::cout << "haha" << std::endl;
}
protected:
void somethingProtected()
{
std::cout << "lala" << std::endl;
}
};
class Derived : public Base
{
public:
void somethingDerived()
{
Base b;
b.somethingPublic(); // Works fine.
somethingProtected(); // This is also fine because accessed by member function.
//b.somethingProtected(); // Error. Called using object b.
//somethingPrivate(); // Error. The function is not inherited by Derived.
}
};