C++派生类构造函数中直接赋值基类成员为何不报错?
C++派生类构造函数中直接赋值基类成员为何不报错?
嘿,你这个问题抓得特别准!其实你是混淆了「成员初始化」和「赋值操作」这两个核心概念,再加上没留意基类成员的访问权限设置,才会有这个疑惑~
咱们一步步拆解:
首先,你说的「子类构造函数不能直接初始化父类成员」是对的,但这里的“初始化”特指构造函数初始化列表阶段的初始化——也就是对象刚被创建时,给成员设置初始值的过程。比如如果你的teacher构造函数写成这样,才会触发报错:
teacher() : _name("teacher") {} // 错误:不能在派生类初始化列表中直接初始化基类成员
而你代码里的_name = "teacher"是赋值操作:这时候基类的成员已经被默认构造函数初始化过了(因为你没显式调用基类构造函数,编译器会自动调用Person的默认构造函数),对象已经完整创建,你只是在修改一个已存在的成员变量的值。这和“初始化”完全是两回事,C++允许这种操作,前提是你有权限访问这个成员。
那为什么你有权限访问_name呢?因为基类里的_name是用protected修饰的。这个访问权限的规则是:基类的protected成员,不仅基类自己能访问,它的派生类(不管是public、protected还是private派生)也能直接访问这些成员。所以你的teacher作为Person的public派生类,完全有资格给_name赋值,编译器自然不会报错。
再给你补个正确初始化基类成员的例子,如果你想在创建teacher对象时就给_name设置初始值,应该调用基类的构造函数:
class Person { protected: string _name; int _age; public: // 给基类加一个带参数的构造函数 Person(const string& name) : _name(name) {} }; class teacher : public Person { public: // 通过初始化列表调用基类的构造函数来初始化_name teacher() : Person("teacher") {} private: string _title; };
这样既符合C++的规则,又能正确初始化基类的成员啦~
备注:内容来源于stack exchange,提问作者ValExi
相关产品推荐
相关产品推荐

