为啥我不能访问派生构造函数的成员初始化列表中继承的受保护字段?
Posted
技术标签:
【中文标题】为啥我不能访问派生构造函数的成员初始化列表中继承的受保护字段?【英文标题】:Why can't I access inherited protected fields in a derived constructor's member initialization list?为什么我不能访问派生构造函数的成员初始化列表中继承的受保护字段? 【发布时间】:2020-11-19 18:40:00 【问题描述】:我是 OOP 的新手。我最近在 C++ 中学习了一些关于继承的知识,protected
字段不能从类外部访问,但可以在继承类中访问。我的代码有一些问题,我不明白出了什么问题:
class Base
protected:
int x;
int y;
int z;
public:
Base(int a, int b): x(a), y(b) cout << "Base constructor" << endl; ;
Base(const Base& prev) : x(prev.x), y(prev.y) cout << "Base copy constructor" << endl; ;
void print_x()
cout << x << endl;
void print_y()
cout << y << endl;
~Base() cout << "Base destructor" << endl; ;
;
class Derived : public Base
public:
Derived(int a, int b): x(a), y(b) cout << "Derived constructor" << endl; ; ////////ERROR : Class
'Derived' does not have any fields named 'x' and 'y'
;
int main()
Base* b = new Base(10, 20);
Derived* d = new Derived(10, 20);
delete b;
delete d;
return 0;
如果Derived
继承Base
,为什么编译器会说Derived
没有x
和y
这两个字段?
【问题讨论】:
【参考方案1】:你可以在Derived
中访问它们,但是它们是Base
的成员,不能直接在Derived
的成员初始化列表中初始化。如果他们是public
,这也行不通。注意Base
类在Derived
的成员初始化之前初始化。
要初始化base,可以在Derived
的成员初始化列表中调用它的构造函数:
class Derived : public Base
public:
Derived(int a, int b) : Base(a, b) ;
;
更多详情请看这里:https://en.cppreference.com/w/cpp/language/constructor
PS:请注意,关于成员初始化列表,与基中 private
的成员也没有区别。基类的所有成员都是继承的,并在派生类的成员初始化之前进行初始化。
您错过了初始化z
,在您的示例中没有理由使用new
和delete
。如果您修复上述问题,您将获得与此代码相同的输出:
int main()
Base b(10,20);
Derived d(10,20);
最后但同样重要的是,如果您打算多态地使用Derived
,您需要将Base
的析构函数声明为virtual
。
【讨论】:
多态使用是什么意思? @Robert 我的意思是Base* b = new Derived();
在这种情况下你不能在Base
中没有虚拟析构函数的情况下调用delete b;
@Robert 即使你现在不这样做,迟早会有人这样做,所以当你公开继承时最好有一个虚拟析构函数
哦!我明白了.. 运行时多态是这样的吗?
@Robert 是的。如果您不打算使用它,您也可以私有继承或使用组合以上是关于为啥我不能访问派生构造函数的成员初始化列表中继承的受保护字段?的主要内容,如果未能解决你的问题,请参考以下文章