如何在初始化类成员前执行代码?(附C++代码示例)
在成员初始化前执行前置代码的可行方法
在你给出的场景中,原代码的写法存在问题——enableCreationOfAObjects()是无返回值的void函数,无法作为逗号运算符的左操作数,且未加括号的情况下,第一个逗号会被解析为构造函数的参数分隔符,导致编译错误。以下是几种在AObject无法修改的前提下,实现成员初始化前执行前置代码的方法:
方法1:利用Lambda表达式初始化
C++11及以上支持在成员初始化列表中使用Lambda表达式,先执行前置代码再构造AObject实例:
void enableCreationOfAObjects(); class AObject { public: AObject(int i, int j, int k); }; class BObject { AObject a; public: BObject() : a( [](){ enableCreationOfAObjects(); return AObject(1, 2, 3); }() ) {} };
Lambda表达式末尾的()会立即执行,先调用enableCreationOfAObjects(),再返回构造好的AObject对象完成成员a的初始化。
方法2:封装辅助创建函数
编写一个全局或类内的辅助函数,在函数内部先执行前置操作,再返回AObject实例:
void enableCreationOfAObjects(); class AObject { public: AObject(int i, int j, int k); }; // 辅助函数 AObject createAObject() { enableCreationOfAObjects(); return AObject(1, 2, 3); } class BObject { AObject a; public: BObject() : a(createAObject()) {} };
通过调用辅助函数,确保前置代码在AObject构造前执行。
方法3:借助基类构造函数
利用C++中基类构造函数优先于派生类成员初始化的特性,创建一个仅用于执行前置代码的基类:
void enableCreationOfAObjects(); class AObject { public: AObject(int i, int j, int k); }; // 用于执行前置代码的基类 class BPreInitializer { public: BPreInitializer() { enableCreationOfAObjects(); } }; class BObject : private BPreInitializer { AObject a; public: BObject() : a(1, 2, 3) {} };
BObject继承自BPreInitializer,实例化时会先调用基类构造函数执行enableCreationOfAObjects(),再初始化成员a。
方法4:修正逗号运算符的使用(仅学术探讨)
若要坚持使用逗号运算符,需解决void表达式无法作为逗号运算符左操作数的问题,可通过static_cast<void>包裹调用将其转为合法表达式:
void enableCreationOfAObjects(); class AObject { public: AObject(int i, int j, int k); }; class BObject { AObject a; public: BObject() : a( (static_cast<void>(enableCreationOfAObjects()), 1), 2, 3 ) {} };
括号确保内部的逗号被解析为逗号运算符:先执行enableCreationOfAObjects(),逗号表达式返回1作为AObject构造的第一个参数。这种写法可读性极差,仅适用于学术研究场景。
内容的提问来源于stack exchange,提问作者Kishore Jonnalagadda
相关产品推荐
相关产品推荐

