Gui*_*i13 1 c++ initialization initializer-list
我有这个类有很多类成员,还有很多不同的构造函数.
到目前为止,我在每个构造函数中使用了构造函数初始化列表,以我想要的方式调优每个成员.
这非常繁琐,因为每次我向我的类添加一个新成员时,我必须访问每个构造函数并更新初始化列表以向该成员添加默认值.
所以,我想我会添加一个方法来初始化我需要的值.问题!由于该方法在初始化列表之后执行,因此我在此初始化列表中放置的特定值将被我的方法覆盖.
快速例子:
class A
{
public:
A();
A( B b );
A( int i );
// A( .... ); plenty of them
private:
int member1, m2, m3,m4;
bool b1,b2, b3;
// ....
// every time I add a member I have to modify the initialization lists
// solution: agregate member initialization in a member function:
void init_members();
}
// init list constructors
A::A() : m1(false), m2(false), m3(false), m4(true) .... // looong list
{
}
A::A( B b) : m1(b.state()), m2(false), m3(false), ... // loong list
{
}
// problem, if I use init_members:
void A::init_members()
{
m1 = false;
m2 = false;
m3 = false;
// ...
}
A::A( int i ) : m1( true)
{
init_members(); // overrides m1 !!!
}
Run Code Online (Sandbox Code Playgroud)
所以,我的问题:我可以混合列表初始化器和方法初始化器,以便列表初始化器优先于方法初始化器吗?
在上面的例子中,我希望m1留true在最后一个构造函数中.
注意:我知道我可以在方法调用之后移动初始化列表,但这意味着我将两次赋值给成员:一旦进入init_members(),然后在构造函数中覆盖它.不够理想:-)
我希望有一些小技巧,如果你有库存.
在C++ 11中,一个选项可以是构造函数委托,其中一个构造函数只是调用其他构造函数之一,以避免重复代码.
这就是它的样子:
class A {
public:
A(int,int,double);
A(int,int);
A(double);
A();
private:
...
};
A::A(int a,int b,double c) {
// the real work to initialize the class
}
// A(int,int) delegates to A(int,int,double), passing along a
// default value for the double
A::A(int a,int b) : A(a,b,0.0) {}
A::A(double c) : A(1,2,c) {} // A(double) delegates to A(int,int,double)
A::A() : A(1.0) {} // A() delegates to A(double)
Run Code Online (Sandbox Code Playgroud)
确保不创建任何循环.通常,您还需要一个构造函数来完成大部分实际工作,而其他构造函数只需编组它们想要传递给该构造函数的值.我们称之为"指定构造函数".指定的构造函数应该是获取最多参数并且不使用任何默认值的构造函数.最终,所有构造函数都应该直接或间接地调用指定的构造函数.
注意模式:使用某些默认值的构造函数将这些默认值传递给使用较少默认值的构造函数,直到您到达没有默认值的函数.这与您尝试使用init_members()方法的方法相反.你有一个设置所有默认值的函数,然后你尝试覆盖它们中的一些.如果您不能使用C++ 11功能,那么最好模拟指定的构造函数模式:init_members()将是您指定的初始化程序,它将没有任何默认值.您可以为每个构造函数使用初始化方法,该构造函数接受它给出的参数,并抛出一些默认值来调用另一个init_members重载.
但是,指定的初始化程序/构造函数的一个问题是默认值遍布整个地方.除了委托之外,C++ 11中的另一个选项是"类内初始化",它允许将所有默认值收集在一起.
class A {
public:
A(int,int,double);
A(int,int);
A(double);
A();
private:
int a = 1,b = 2; // in-class initialization gathers all the defaults together
double c = 1.0;
};
Run Code Online (Sandbox Code Playgroud)
鉴于上述情况,所有构造函数都会自动将成员值初始化为这些默认值,除非您将其显式初始化为该构造函数中的其他内容.
A::A(int a,int b,double c) : a(a), b(b), c(c) {}
A::A(int a,int b) : a(a), b(b) {} // member c is automatically initialized to 1.0
A::A(double c) : c(c) {} // members a and be are automatically initialized to 1 and 2
A::A() {}; // all members are initialized with their in-class values.
Run Code Online (Sandbox Code Playgroud)
以下是使用示例init_members():
class A {
public:
A(int a,int b,double c) { init_members(a,b,c); }
A(int a,int b) { init_members(a,b); }
A(double c) {init_members(c);}
A() { init_members(); }
private:
void init_members(int,int,double) { ... }
void init_members(int a,int b) { init_members(a,b,1.0); }
void init_members(double c) { init_members(1,2,c); }
void init_members() { init_members(1.0); }
...
};
Run Code Online (Sandbox Code Playgroud)
此方法值在init_members()可以调用之前初始化成员,因此成员初始化两次.我不确定在C++ 03中有办法解决这个问题.
| 归档时间: |
|
| 查看次数: |
462 次 |
| 最近记录: |