#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;
}
我认为可能只有这个的受保护成员可以使用,其他实例的受保护成员永远无法访问。
但:
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
}
};
我感到有些厌恶,因为我已经在C编程了一段时间,但我找不到任何解释这种行为。
编辑:
如果它是相同或不同的实例没有关系:
int main()
{
Derived d1, d2; // Two different instances
d1.somethingDerived(d2); // This compiles fine
d1.somethingDerived(d1); // This compiles fine
return 0;
}
EDIT2:
看来,当涉及到访问权限,它是没有关系的一个类的所有实例被使用:
class Base
{
public:
void something(Base& b) // Another instance
{
++b.a; // But can enter private members
}
private:
int a;
};
最佳答案
即使C中的访问控制基于每个类(而不是每个实例),受保护的访问说明符有一些特殊性。
语言规范想要确保您正在访问属于派生类的某个基本子对象的受保护成员。你不应该能访问基本类型的一些不相关的独立对象的受保护成员。特别是,您不能访问基本类型的独立对象的受保护成员。您只能访问嵌入到派生对象中作为基本子对象的基础对象的受保护成员。
因此,您必须通过pointer->成员语法,reference.member或object.member语法访问受保护的成员,其中指针/引用/对象引用派生类。
这意味着在你的示例中,protected成员somethingProtected()不能通过Base对象访问,Base *指针或Base&引用,但它可以通过Derived对象,Derived *指针和Derived&参考。您的普通somethingProtected()访问是允许的,因为它只是一个缩写 – > somethingProtected(),其中类型为Derived *。
b.somethingProtected()违反了上述要求。
注意按照上面的规则
void Derived::somethingDerived()
{
Base *b = this;
b->somethingProtected(); // ERROR
this->somethingProtected(); // OK
}
第一次调用也将失败,而第二次调用将编译,即使两者都尝试访问同一个实体。
相关文章
转载注明原文:c++ 为什么在这段代码中派生类不能调用受保护的成员函数? - 代码日志