C++模板、多重继承与非默认构造函数的初始化问题解决
问题解决:虚继承下非默认构造基类的初始化问题
原因分析
- 虚基类初始化规则:C++中,虚基类的实例由最派生类负责初始化,中间派生类对虚基类的初始化会被忽略。但如果虚基类没有默认构造函数,所有继承它的中间类(此处的
Test<T>)的默认构造函数会被编译器自动删除——因为编译器无法生成能合法初始化虚基类的默认构造逻辑。 MultiTest的构造依赖缺失:MultiTest继承了Test<float>和Test<double>,这两个类的默认构造已被删除,且没有自定义构造函数,导致MultiTest无法调用它们的构造函数;同时MultiTest自身也没有定义能初始化Base的构造函数,因此编译报错。
解决方案
需要两步修改:
1. 给Test模板类添加合法构造函数
给Test<T>添加带参数的构造函数,显式传递参数给Base,确保Test类有可调用的构造函数:
template<typename T> class Test: public virtual Base { public: explicit Test(int data) : Base(data) {} // 新增构造函数,传递参数给Base virtual int foo(T x) const { return x + m_data; } };
2. 在MultiTest中定义构造函数完成全量初始化
MultiTest作为最派生类,需要同时初始化虚基类Base,并调用两个Test特化类的构造函数(虽然Test中的Base初始化会被忽略,但必须调用其构造函数以满足编译要求):
class MultiTest : public Test<float>, public Test<double> { public: explicit MultiTest(int data) : Base(data), Test<float>(data), Test<double>(data) {} int foo(float x) const override { return x * static_cast<float>(boilerplate(3)); } int foo(double x) const override { return x / static_cast<double>(boilerplate(10)); } };
修改后,main中的MultiTest x{32};即可正常编译运行。
内容的提问来源于stack exchange,提问作者Mad Physicist
相关产品推荐
相关产品推荐

