c++ - 有没有办法在构造函数代码中初始化类的成员对象而不是初始化列表?
问题描述
考虑我想在一个对象中包装一些库代码。该库需要通过调用该包装类的构造函数中的某个函数来设置和初始化。
图书馆的“对象”然后分散到创建更多不同的“对象”,包装类以另一个包装对象的形式包装,该对象应该是该类的普通成员。
但在我看来,类的成员只能通过在构造函数的初始化列表中调用它们的构造函数来初始化或创建。这些代码位的执行先于执行库及其环境初始化的实际类的构造函数,这使我无法将该成员对象实际初始化为成员,而是强制我将其初始化为指向第二个包装器,因为它的构造器必须在第一个构造器的代码中手动调用。
例子:
class A {
public:
A() {
if(!wrapped_library_init()) {
exit(CRITICAL_ERROR);
}
ptr_to_some_library_metadata *a = library_function(); /*Needs to
be called after wrapped_library_init() or needs a pointer to some
wrapped object created inside this constructor */
//initialize b
}
private:
B b; //Wants to be a member but can not
};
class B {
B(ptr_to_some_library_metadata *a);
}
解决方案
成员对象只能在成员初始化器列表中构造。不过,有一些技术可用于初始化对象:
在返回合适的对象之前,使用辅助 lambda 函数做必要的额外工作。例如:
A() : B([]{ if (!wrapped_library_init()) { exit(CRITICAL_ERROR); } return library_function(); }()) { }
union
您可以通过仅使用适当的成员来延迟构造。使用此技术时,需要显式破坏成员,例如:class A { union Bu { B b }; Bu b; public: A() { if (!wrapped_library_init()) { exit(CRITICAL_ERROR); } new(&b.b) B(library_function()); } ~A() { b.b.~B(); } // ... };
我个人会使用第一种方法。但是,在某些情况下,使用 aunion
来延迟构造是有帮助的。
推荐阅读
- angular - 如何使用 angular8 和 bootstrap datetimepicker 将日历设置为从选定日期开始的一年
- .net - 本地开发环境中的 Azure WebJobs UseDevelopmentStorage=true
- python - 数据整形(11709、25,4435)上的 LSTM 不起作用
- python - 修改listview Django中的字段格式
- python - 标量变量 seaborn.lmplot 的索引无效
- r - 堆叠条形图 R 中的顺序
- c - 使用 libsodium 在 C 中生成伪随机数
- python - 数据中的 Python 读取无法按预期工作
- c# - 如何防止在 VS Code 扩展中的 C# FixFormat 中的“if”和左括号之间添加空格?
- node.js - 本地公共文件夹中的 json 文件