在构造函数代码之前禁用默认类成员初始化 在C++中,在成员的构造函数被执行之前默认构造一个在成员初始化列表中未构造的类的任何成员。但是,如果该成员变量只是在它所在的类的构造函数中构造,那么这似乎是非常浪费的
下面我举了一个例子来说明我的意思。这里,示例类有一个类型为LargeIntimidatingClass的成员变量x。使用成员初始化列表,示例x中的第一个构造函数只构造一次。但是,如果不能使用成员初始化列表合理地构造x,则会构造两次在构造函数代码之前禁用默认类成员初始化 在C++中,在成员的构造函数被执行之前默认构造一个在成员初始化列表中未构造的类的任何成员。但是,如果该成员变量只是在它所在的类的构造函数中构造,那么这似乎是非常浪费的,c++,default-constructor,member-initialization,C++,Default Constructor,Member Initialization,下面我举了一个例子来说明我的意思。这里,示例类有一个类型为LargeIntimidatingClass的成员变量x。使用成员初始化列表,示例x中的第一个构造函数只构造一次。但是,如果不能使用成员初始化列表合理地构造x,则会构造两次 //This class used as part of the example class further below class LargeIntimidatingClass { // ... //many member variables and
//This class used as part of the example class further below
class LargeIntimidatingClass {
// ...
//many member variables and functions
// ...
LargeIntimidatingClass() {
//Painfully expensive default initializer
}
LargeIntimidatingClass(int a, double b) {
//Complicated calculations involving a and b
}
};
//Here, this class has a LargeIntimidatingClass as a member variable.
class Example {
LargeIntimidatingClass x;
char c;
//Basic member initialization list constructor. Efficient!
Example(int a, double b, char c) : x(a,b), c(c) {}
//What if the parameters to the LargeIntimidatingClass's constructor
//need to be computed inside the Example's constructor beforehand?
Example(std::string sophisticatedArgument) {
//Oh no! x has already been default initialized (unnecessarily!)
int a = something1(sophisticatedArgument);
double b = something2(sophisticatedArgument);
//x gets constructed again! Previous (default) x is totally wasted!
x = LargeIntimidatingClass(a,b);
c = something3(sophisticatedArgument);
}
};
是的,我意识到在这个愚蠢的示例中,您可以编写Examplestring s:xf1s、f2s、cf3s{},但我相信您可以想象这样一种情况:将一堆逻辑推到成员初始化列表中是很麻烦的,甚至是不可能的
当成员变量未在成员初始化列表中列出时,是否可以禁用该成员变量的默认构造函数
当成员变量未在成员初始化列表中列出时,是否可以禁用该成员变量的默认构造函数
不,那是不可能的
当成员变量未在成员初始化列表中列出时,是否可以禁用该成员变量的默认构造函数
不,那是不可能的。禁用语言工作方式的一个组成部分?不需要。但是你可以通过重构来使用该语言,也可以通过各种方式绕过它 有一个指向扩展类的智能指针成员。 将成员设置为std:aligned_storage,并通过放置新对象来创建对象。然后自己小心地管理对象的生命周期。 持有std:可选。管理初始化,并让库类型管理其余部分,以减少对象大小方面的开销。
禁用语言工作方式的一个组成部分?不需要。但是你可以通过重构来使用该语言,也可以通过各种方式绕过它 有一个指向扩展类的智能指针成员。 将成员设置为std:aligned_storage,并通过放置新对象来创建对象。然后自己小心地管理对象的生命周期。 持有std:可选。管理初始化,并让库类型管理其余部分,以减少对象大小方面的开销。
不能禁用构造。在到达构造函数主体之前,必须初始化所有类成员。也就是说,你可以很容易地解决这个问题。您可以添加一个私有静态成员函数,该函数获取a和b并从中返回一个大的AntiMidatingClass,如下所示
class Example {
LargeIntimidatingClass x;
char c;
static LargeIntimidatingClass make_LargeIntimidatingClass(std::string sophisticatedArgument)
{
int a = something1(sophisticatedArgument);
double b = something2(sophisticatedArgument);
return LargeIntimidatingClass(a,b);
}
static char make_c(std::string sophisticatedArgument)
{
return something3(sophisticatedArgument);
}
public:
//Basic member initialization list constructor. Efficient!
Example(int a, double b, char c) : x(a,b), c(c) {}
// now we use helpers to initialize in the member initialization list
Example(std::string sophisticatedArgument) : x(make_LargeIntimidatingClass(sophisticatedArgument), c(make_c(sophisticatedArgument) {
//now everything is initialized correctly
}
};
不能禁用构造。在到达构造函数主体之前,必须初始化所有类成员。也就是说,你可以很容易地解决这个问题。您可以添加一个私有静态成员函数,该函数获取a和b并从中返回一个大的AntiMidatingClass,如下所示
class Example {
LargeIntimidatingClass x;
char c;
static LargeIntimidatingClass make_LargeIntimidatingClass(std::string sophisticatedArgument)
{
int a = something1(sophisticatedArgument);
double b = something2(sophisticatedArgument);
return LargeIntimidatingClass(a,b);
}
static char make_c(std::string sophisticatedArgument)
{
return something3(sophisticatedArgument);
}
public:
//Basic member initialization list constructor. Efficient!
Example(int a, double b, char c) : x(a,b), c(c) {}
// now we use helpers to initialize in the member initialization list
Example(std::string sophisticatedArgument) : x(make_LargeIntimidatingClass(sophisticatedArgument), c(make_c(sophisticatedArgument) {
//now everything is initialized correctly
}
};