C++抽象类继承中两种构造写法的适用场景及正确性确认
C++抽象基类与子类构造写法问题解答
当前Son构造函数写法的正确性
当前写法是否合法,核心取决于Father类中m_name、m_properties的访问权限:
- 如果这两个成员是
protected或public:语法上合法,但不是最优实现——父类成员会先被默认构造初始化,再执行子类构造里的赋值操作,多了一次冗余步骤; - 如果这两个成员是
private:直接编译错误,因为子类无权访问父类私有成员。
另外要明确:抽象基类完全可以定义带参构造函数,只是不能直接实例化而已。如果Father没有定义任何构造函数,编译器会自动生成默认构造,这也是当前写法能运行的前提之一。
两种构造写法的适用场景
1. 函数体内赋值的写法
- 仅适用于父类未提供合适的带参构造,且父类成员允许子类直接访问(
protected/public)的场景; - 或者当赋值逻辑复杂(比如需要先做条件判断、计算推导,再给父类成员赋值),无法在初始化列表中完成的情况;
- 缺点是效率偏低,且破坏封装性(子类直接操作父类成员)。
2. 初始化列表调用父类带参构造的写法
- 这是C++对象初始化的最佳实践,适用于父类已定义带参构造的场景;
- 优势:直接在对象初始化阶段完成父类成员的赋值,避免默认构造+二次赋值的额外开销,同时能保证父类成员的封装性(比如把
m_name、m_properties设为private,仅通过父类构造初始化); - 哪怕Father是抽象基类,只要定义了带参构造(通常设为
protected),子类就可以在初始化列表中调用它——抽象基类的构造是用来初始化子类对象的父类部分,完全合法。
优化建议
如果当前Father没有带参构造,建议给它添加一个protected的带参构造函数,将m_name、m_properties设为private,然后Son的构造函数通过初始化列表调用父类带参构造,同时初始化自己的m_school成员,既保证封装性,又提升初始化效率。
内容的提问来源于stack exchange,提问作者Mirek
相关产品推荐
相关产品推荐

