c++ - c++ 从父类实例化一个受保护的成员
问题描述
下面的代码显示了 2 个类 person 和 trouble_maker。在这个例子中,我有点困惑为什么 trouble_maker 类没有权限在实例化列表中设置它直接从 person 继承的变量名。为什么在我能够设置变量名之前必须创建 Trouble_maker 对象?
#include <string>
class person {
int age;
public:
person(int age);
protected:
std::string name;
};
person::person(int age) : age(age) {
}
class trouble_maker : person {
public:
trouble_maker(std::string name, int age);
};
trouble_maker::trouble_maker(std::string name, int age) : person(age), name(name) //name is not a static memeber
{
this->name = name; // works fine
}
int main() {
person a_person();
return 0;
}
解决方案
构造函数头部之后的成员初始化器列表:
不进行任何变量赋值。相反,它为类的每个非静态直接数据成员和基类指定了一个初始化程序,这些成员或基类将被初始化。
name
不是 的直接成员trouble_maker
。trouble_maker
初始化它不是工作。那是person
的工作。
成员和基类是自顶向下初始化的。首先初始化基类,然后初始化类的直接成员。在person
创建和初始化子对象时,派生trouble_maker
对象甚至还不存在。因此必须是person
初始化name
。
如果您想以name
不同于 introuble_maker
的方式进行初始化person
,则需要编写一个构造person
函数来为trouble_maker
. trouble_maker
然后可以在成员初始值设定项列表中调用此构造函数,就像您在此处所做的一样: person(age),
:
后者this->name = name;
不是初始化,而是赋值。由于你做了name
protected
而不是private
,trouble_maker
允许分配给name
,但它仍然无法在name
不通过构造函数的情况下进行初始化person
。
推荐阅读
- java - 输出和解释是什么?
- android - 关于 Ad Mob 插页式广告的问题
- javascript - Firebase 存储中的奇怪行为
- wpf - 在 DataGridColumn 中使用资源中的 ControlTemplate
- javascript - 多次应用替换(使用 Javascript 动态)
- amazon-ec2 - VPN IKE 重新协商导致 Glassfish 中的数据库连接断开
- django - 无法覆盖模型 save()
- php - 完全排除 Woocommerce 中运输的所有邮政信箱变体
- c++ - 错误:对“set_union”的调用没有匹配
- javascript - 为什么我的对象没有将数据填充到图表中?(包括演示)