正确地初始化C ++成员变量的正确方法? [英] Right way to conditionally initialize a C++ member variable?
问题描述
我确定这是一个非常简单的问题.以下代码显示了我正在尝试做的事情:
I'm sure this is a really simple question. The following code shows what I'm trying to do:
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
,但我希望有一种更简单的方法.
This doesn't compile, because m_class
is being created with an empty constructor (which doesn't exist). What is the right way of doing this? My guess is using pointers and instantiating m_class
using new
, but I'm hoping there is an easier way.
我应该早先说过,但是我的实际问题还有一个额外的麻烦:我需要在初始化m_class之前调用一个方法,以设置环境.因此:
I should have said earlier, but my actual problem has an additional complication: I need to call a method before initializing m_class, in order to set up the environment. So:
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);
}
};
是否可以通过精美的初始化列表技巧来实现这一目标?
Is it possible to achieve this with fancy initialization list tricks?
推荐答案
使用条件运算符.如果表达式较大,请使用函数
Use the conditional operator. If the expression is larger, use a function
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
To call a function before initializing m_class, you can place a struct before that member and leverage 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
的非静态成员函数.该功能必须是其基类的成员,并且基类的ctor必须已经完成才能正常工作.
This will call do_something()
before initializing m_class
. Note that you are not allowed to call non-static member functions of MyClass
before the constructor initializer list has completed. The function would have to be a member of its base class and the base class' ctor must already be completed for that to work.
还请注意,对于创建的每个单独对象,当然总是调用该函数-不仅是针对创建的第一个对象.如果要这样做,可以在初始化程序的构造函数中创建一个静态变量:
Also note that the function, of course, is always called, for each separate object created - not only for the first object created. If you want to do that, you could create a static variable within the initializer's constructor:
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)) {
}
};
它使用逗号运算符.请注意,您可以使用function-try块
It's using the comma operator. Note that you can catch any exception thrown by do_something
by using a function-try block
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
对象失败的异常,则下次将再次调用该函数.希望这会有所帮助:)
The do_something
function will be called again next time, if it threw that exception that caused the MyClass
object fail to be created. Hope this helps :)
这篇关于正确地初始化C ++成员变量的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!