#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;
}
Run Code Online (Sandbox Code Playgroud)
我想也许只有受保护的成员this可以使用,其他实例的受保护成员永远无法访问.
但:
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
}
};
Run Code Online (Sandbox Code Playgroud)
我觉得有点恶心,因为我已经用C++编程了一段时间,但是我找不到任何关于这种行为的解释.
编辑:
它是相同还是不同的实例无关紧要:
int main()
{
Derived d1, d2; // Two different instances
d1.somethingDerived(d2); // This compiles fine
d1.somethingDerived(d1); // This compiles fine
return 0;
}
Run Code Online (Sandbox Code Playgroud)
EDIT2:
似乎在访问权限时,根本使用的是什么类的实例并不重要:
class Base
{
public:
void something(Base& b) // Another instance
{
++b.a; // But can enter private members
}
private:
int a;
};
Run Code Online (Sandbox Code Playgroud)
AnT*_*AnT 75
尽管C++中的访问控制基于每个类工作(而不是基于每个实例),但protected访问说明符具有一些特殊性.
语言规范要确保您正在访问属于派生类的某个基础子对象的受保护成员.您不应该能够访问某些不相关的基类型独立对象的受保护成员.特别是,您无法访问基类型的独立对象的受保护成员.您只能访问作为基础子对象嵌入到派生对象中的基础对象的受保护成员.
因此,您必须通过pointer->member语法reference.member或object.member语法访问受保护的成员,其中指针/引用/对象引用派生类.
这意味着在您的示例中,受保护的成员somethingProtected()不能通过Base对象,Base *指针或Base &引用访问,但可以通过Derived对象,Derived *指针和Derived &引用访问它.你的普通somethingProtected()访问是不允许的,因为它仅仅是一个速记this->somethingProtected()这里this是类型的Derived *.
b.somethingProtected() 违反了上述要求.
注意按照上面的规则
void Derived::somethingDerived()
{
Base *b = this;
b->somethingProtected(); // ERROR
this->somethingProtected(); // OK
}
Run Code Online (Sandbox Code Playgroud)
即使两者都试图访问同一个实体,第一个调用也将失败而第二个调用将编译.