C++多级继承中如何用一个构造函数初始化所有层级类?
多级继承中构造函数跨层级初始化问题
原始代码
#include <iostream> using namespace std; class alpha { int a; public: alpha () {}; alpha (int c) { a = c; } void showalpha (void) { cout << "\nalpha, a = " << a; } }; class beta : public alpha { float b; public: beta () {}; beta (float c) { b = c; } void showbeta (void) { cout << "\nbeta, b = " << b; } }; class gamma : public beta { float c; public: gamma () {}; gamma (float b, float d): beta (b) { c = d; } void showgamma (void) { cout << "\ngamma, c = " << c; } }; int main () { gamma A (5.6, 7.6); A.showalpha (); A.showbeta (); A.showgamma (); return 0; }
问题描述
能否修改gamma类的构造函数(即:
gamma (float b, float d): beta (b) { c = d; }
),使其通过一个构造函数完成alpha、beta、gamma三个类(多级继承中的所有类)的初始化?
我尝试了如下代码:
gamma (int a, float b, float d): alpha (a), beta (b) { c = d; }
但编译报错:type ‘alpha’ is not a direct base of ‘gamma’
问题原因
C++的多级继承规则里,派生类只能直接初始化自己的直接基类,不能跳过中间层直接初始化间接基类。gamma的直接基类是beta,alpha是它的间接基类,所以直接在gamma的构造函数初始化列表里调用alpha(a)是不允许的。
解决方案
要实现gamma一次性初始化所有层级的类,需要修改中间基类beta的构造函数,让它能接收初始化alpha的参数并传递给alpha的构造函数,然后gamma再把所有参数传递给beta的新构造函数。
具体修改步骤
- 给
beta新增一个构造函数,同时接收alpha的初始化参数和自身成员b的参数:
beta(int a_val, float b_val) : alpha(a_val) { b = b_val; }
- 修改
gamma的构造函数,接受三个参数,在初始化列表里调用beta的新构造函数,传递alpha和beta的初始化参数:
gamma(int a_val, float b_val, float c_val) : beta(a_val, b_val) { c = c_val; }
修改后的完整代码
#include <iostream> using namespace std; class alpha { int a; public: alpha () {}; alpha (int c) { a = c; } void showalpha (void) { cout << "\nalpha, a = " << a; } }; class beta : public alpha { float b; public: beta () {}; beta (float c) { b = c; } // 新增构造函数,传递参数给alpha beta(int a_val, float b_val) : alpha(a_val) { b = b_val; } void showbeta (void) { cout << "\nbeta, b = " << b; } }; class gamma : public beta { float c; public: gamma () {}; gamma (float b, float d): beta (b) { c = d; } // 修改后的构造函数,一次性初始化所有层级 gamma(int a_val, float b_val, float c_val) : beta(a_val, b_val) { c = c_val; } void showgamma (void) { cout << "\ngamma, c = " << c; } }; int main () { // 使用新构造函数初始化所有成员 gamma A (10, 5.6, 7.6); A.showalpha (); A.showbeta (); A.showgamma (); return 0; }
补充说明
如果用的是C++11及以上版本,也可以通过using声明让gamma继承beta的构造函数,但这种方式只适用于参数完全匹配的场景,灵活性不如修改中间基类构造函数的方法。比如在gamma类中添加:
using beta::beta;
但这只能复用beta已有的构造逻辑,无法直接扩展初始化alpha的参数传递,所以还是推荐前面的解决方案。
内容的提问来源于stack exchange,提问作者Vinayak Deshmukh
相关产品推荐
相关产品推荐

