无法访问受保护的成员
Cannot access protected member
我不明白下面的内容,当Derived
继承Base
时,它可以访问其受保护的成员,这些成员可以通过派生函数访问。但是,如果Base
类试图从Derived
类访问它自己的成员(它本身允许访问Base
),它没有访问,为什么?
class Base {
protected:
int x;
};
class Derived : Base {
public:
void foo(Base* b);
};
void Derived::foo(Base* b) {
b->x = 2; // cannot access protected member,
// though Derived inherits from Base, why?
}
一个常见的误解。
在Derived::foo()
内部,可以访问Derived
类对象的受保护基成员。但是,*b
是而不是Derived
类型的。相反,它的类型是Base
,因此它与您的类没有任何关系。
如果你把Derived*
作为参数,这是另一回事——那么你确实可以访问受保护的基本成员。
让我们拼出来:
struct Derived;
struct Base
{
int f(Derived *);
protected:
int x;
private:
int y;
};
struct Derived : public Base
{
int g(Base *);
int h(Derived *);
};
int Derived::g(Base * b)
{
return b->x; // error, protected member of unrelated class
return b->y; // error, private member of different class
}
int Derived::h(Derived * d)
{
return d->x; // OK, protected base member accessible in derived class
return d->y; // error, private member of different class
}
int Base::f(Derived * d)
{
return d->x; // OK, d converts to Base*
return d->y; // OK, ditto
}
你正好碰到了标准中的一个特殊规则:
这个附加的访问检查的一个原因是关于那些基类受保护成员的行为。由于成员是受保护的,因此不同的派生类可以向这些派生成员添加语义,甚至可以对其意义进行全面更改。(这就是为什么受保护的数据相当危险的原因之一。)由于您的类不会注意到其他派生类对基类语义所做的这些添加/修改,因此最好的方法是在通过基类访问时排除对基类成员的访问。11.5受保护成员访问
当派生类的友元或成员函数引用基类的受保护的非静态成员函数或受保护的非静态数据成员时,除第11条中所述的访问检查外,还应用访问检查。除形成指向成员的指针外,*访问必须通过指向派生类本身(或从该类派生的任何类)的指针、引用或对象。
提供别人所说的具体例子:
class Base {
protected:
int x;
};
class Derived : Base {
public:
void foo(Derived*, Base*);
};
int main() {
Base fiddle;
Derived fast, furious;
fast.foo(&furious, &fiddle);
}
void Derived::foo(Derived *d, Base* b) {
x = 1; // Legal, updates fast.x
this->x = 2; // Legal, updates fast.x
d->x = 3; // Legal, updates furious.x
b->x = 4; // Error, would have updated fiddle.x
}
您的想法是正确的,但是您没有正确地使用受保护的成员。
void foo(Base* b)应该改为void foo();
,它的实现是:
void派生::foo() {返回这个-> x;}
因为x是受保护的成员,所以你不能从另一个对象访问它——即使这个对象继承了这个类。您只能从派生对象本身访问它。
您实际上所做的是创建一个base实例,它与派生的关系与派生的内部base实例的关系不同。将变量设置为protected使继承的类可以访问它自己的内部base实例。但是,在类中创建base类型的对象是不同的,因此不允许访问。
相关文章:
- C++:无法访问声明的受保护成员
- 继承和友元函数,从基类访问受保护的成员
- 为什么派生类的好友不能使用受保护的成员?
- 相同的层次结构,访问基类的受保护成员时的行为不同
- 从模板化父类中的派生内部类访问受保护的成员变量
- 在使用受保护和继承时无法访问在类中声明的私有成员
- 同一模板类但模板类型的受保护成员
- 派生类无法访问基类的受保护成员
- 继承期间受保护成员的皮条
- 访问说明符(私有/公共/受保护)如何在内部工作(限制成员访问)?
- 如何将超类的受保护成员访问到其派生类. 如果已在派生类中声明了具有相同名称的函数?
- 是否可以基于私有/受保护成员分配类枚举?
- 依赖模板基础的受保护成员
- 将派生类构造函数参数传递给受保护的成员
- 无法从派生类型的作用域访问另一个实例的受保护成员
- 为什么我无法使用受保护/私有继承访问派生实例中基类的受保护成员?
- 将对象强制转换为派生类以访问父类的受保护成员
- 使从一个基类派生的类能够使用继承的受保护成员
- 无法访问派生类函数内的基类的受保护数据成员
- 派生类如何使用基类的受保护成员