gpt4 book ai didi

c++ - 有条件地初始化 C++ 成员变量的正确方法?

转载 作者:可可西里 更新时间:2023-11-01 14:52:30 25 4
gpt4 key购买 nike

我敢肯定这是一个非常简单的问题。以下代码显示了我正在尝试做的事情:

class MemberClass {
public:
MemberClass(int abc){ }
};

class MyClass {
public:
MemberClass m_class;
MyClass(int xyz) {
if(xyz == 42)
m_class = MemberClass(12);
else
m_class = MemberClass(32);
}
};

这不会编译,因为 m_class 是用一个空构造函数(不存在)创建的。这样做的正确方法是什么?我的猜测是使用指针并使用 new 实例化 m_class,但我希望有更简单的方法。

编辑: 我应该早点说,但我的实际问题有一个额外的复杂性:我需要在初始化 m_class 之前调用一个方法,以便设置环境。所以:

class MyClass {
public:
MemberClass m_class;
MyClass(int xyz) {
do_something(); // this must happen before m_class is created
if(xyz == 42)
m_class = MemberClass(12);
else
m_class = MemberClass(32);
}
};

是否可以通过花哨的初始化列表技巧来实现这一点?

最佳答案

使用条件运算符。如果表达式较大,则使用函数

class MyClass {
public:
MemberClass m_class;
MyClass(int xyz) : m_class(xyz == 42 ? 12 : 32) {

}
};

class MyClass {
static int classInit(int n) { ... }
public:
MemberClass m_class;
MyClass(int xyz) : m_class(classInit(xyz)) {

}
};

要在初始化 m_class 之前调用一个函数,您可以在该成员之前放置一个结构并利用 RAII

class MyClass {
static int classInit(int n) { ... }
struct EnvironmentInitializer {
EnvironmentInitializer() {
do_something();
}
} env_initializer;
public:
MemberClass m_class;
MyClass(int xyz) : m_class(classInit(xyz)) {

}
};

这将在初始化 m_class 之前调用 do_something()。请注意,在构造函数初始化列表完成之前,您不得调用 MyClass 的非静态成员函数。该函数必须是其基类的成员,并且基类的构造函数必须已经完成才能工作。

另请注意,当然,对于创建的每个单独对象,始终会调用该函数 - 而不仅仅是针对创建的第一个对象。如果你想这样做,你可以在初始化器的构造函数中创建一个静态变量:

class MyClass {
static int classInit(int n) { ... }
struct EnvironmentInitializer {
EnvironmentInitializer() {
static int only_once = (do_something(), 0);
}
} env_initializer;
public:
MemberClass m_class;
MyClass(int xyz) : m_class(classInit(xyz)) {

}
};

它使用逗号运算符。请注意,您可以使用函数尝试 block 捕获 do_something 抛出的任何异常

class MyClass {
static int classInit(int n) { ... }
struct EnvironmentInitializer {
EnvironmentInitializer() {
static int only_once = (do_something(), 0);
}
} env_initializer;
public:
MemberClass m_class;
MyClass(int xyz) try : m_class(classInit(xyz)) {

} catch(...) { /* handle exception */ }
};

如果 do_something 函数抛出导致 MyClass 对象创建失败的异常,下次将再次调用该函数。希望这会有所帮助:)

关于c++ - 有条件地初始化 C++ 成员变量的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1014518/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com