C++含虚方法基类的子类如何用initializer_list初始化实例
问题解决方法
首先,你的代码编译报错的核心原因是:X继承了基类Y且包含虚析构,不符合C++中聚合类的定义,因此无法直接使用单元素的列表初始化语法——这种语法仅支持聚合类或有对应构造函数的类。另外需要注意,基类Y的纯虚析构必须提供定义,否则会出现链接错误。
以下是两种无需大幅修改类的简单解决方法:
方法一:添加极简构造函数
给X添加一个仅用于初始化msg成员的构造函数,这是侵入性最小的修改:
#include <string> using namespace std; struct Y { virtual ~Y() = 0; }; // 必须定义纯虚析构,避免链接错误 Y::~Y() {} struct X : public Y { string msg; virtual ~X() = default; // 新增构造函数,直接初始化msg X(string s) : msg(move(s)) {} }; int main() { X x{"Some string"}; // 现在可正常编译 return 0; }
方法二:显式初始化基类(仅适用于C++17及以后,不推荐实际使用)
如果临时去掉X的虚析构(但强烈不推荐,因为基类有虚方法,析构非虚会导致Y*指针销毁X对象时的资源泄漏风险),X在C++17中属于允许包含基类的聚合类,此时可以显式初始化基类部分:
#include <string> using namespace std; struct Y { virtual ~Y() = 0; }; Y::~Y() {} struct X : public Y { string msg; // 去掉虚析构,仅作演示 ~X() = default; }; int main() { // 显式初始化基类(空括号代表默认初始化基类) X x{{}, "Some string"}; return 0; }
重点提示:方法二仅作语法演示,实际项目中务必保留X的虚析构,避免内存泄漏风险,因此优先选择方法一。
内容的提问来源于stack exchange,提问作者Mikhail
相关产品推荐
相关产品推荐

