我正在尝试一些有关继承的程序,结果发现以下内容引起了错误,但我并不真正了解其原理。
#include <iostream>
using namespace std;
class Base {
protected:
int x = 0;
};
class Derived: public Base {
// OK: access protected member via this
void g() { cout<<x; }
// OK: access protected member of other Derived
void h(Derived& d) { cout<<d.x; }
// FAIL: access Base class's protected member, why?
void f(Base& b) { cout<<b.x; }
};
int main() {}
我希望Derived类可以访问基类的公共或受保护的数据成员和成员函数。
但是它没有按照我的想法工作,有人可以帮助我阐明我的概念吗?
答案 0 :(得分:2)
void f(Base& b) {cout<<b.x;}
在这里,您尝试访问其他类的受保护成员。您也共享相同的基类并不重要。 (仍在寻找来源)
void g() {cout<<x;}
在此示例中,您将拥有自己的私人成员。 (基类的受保护成员在派生类中继承和保护)
void h(Derived& d) {cout<<d.x;}
在这里您正在访问同一班的私人成员。但有关更多信息,请参见以下帖子:Access private elements of object of same class
答案 1 :(得分:1)
没有比您已经发现的更多的东西了。派生实例可以访问其受保护成员以及其他派生实例的成员,但不能访问基类实例的成员。为什么?因为这就是protected
按照定义的工作方式。
有关更多详细信息,请参考cppreference(强调我的观点):
只能访问基类的受保护成员
1)由Base的成员和朋友
2)由成员和朋友(直到 C ++ 17)源自Base的任何类,,但仅适用于在 从Base(包括此)派生的类型的对象
答案 2 :(得分:1)
只能访问基类的受保护成员
由Base的成员和朋友
这不是您的情况
由成员和朋友(直到 C ++ 17)从Base派生的任何类,但仅当在 从Base(包括此)派生的类型的对象
这是您的情况,但是参数
b
不是这种派生类型
受保护成员访问的原因是允许基类定义供派生类使用的接口。 与允许每个不同的派生类型对每个基类对象有特殊访问权限不同。
答案 3 :(得分:0)
您问题中的代码似乎像cppreference网站上的示例,在代码注释中我们可以看到关于该限制的很好的解释:
struct Base {
protected:
int i;
private:
void g(Base& b, struct Derived& d);
};
struct Derived : Base {
void f(Base& b, Derived& d) // member function of a derived class
{
++d.i; // okay: the type of d is Derived
++i; // okay: the type of the implied '*this' is Derived
// ++b.i; // error: can't access a protected member through Base
// (Otherwise it would be possible to change other derived classes,
// like a hypothetical Derived2, base implementation)
}
};
所以,如果您有
class Derived2: public Base {
};
不允许Derived
类访问Derived2
受保护的属性,因为它不是Derived2
的子级。 protected
的目的不是允许兄弟姐妹,而是允许孩子对成员进行访问。
标准中的全部详细信息: