c++ - 在构造函数代码之前禁用默认类成员初始化

标签 c++ default-constructor member-initialization

在 C++ 中,不是在成员初始化列表中构造的类的任何成员都是在执行包含类的构造函数之前默认构造的。但是,如果该成员变量只是要在它所在的类的构造函数中构造,这似乎是非常浪费的。

我在下面提供了一个示例来阐明我的意思。这里,Example 类有一个类型为 LargeIntimidatingClass 的成员变量 x。使用成员初始化列表(Example 中的第一个构造函数)x 仅构造一次。然而,如果x不能使用成员初始化列表合理构造,它会被构造两次!

//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);
    }
};

是的,我知道在这个愚蠢的例子中你可以写成 Example(string s) : x(f1(s),f2(s)), c(f3(s)) {} ,但我相信您可以想象这样一种情况,将一堆逻辑插入成员初始化列表是很麻烦的(甚至是不可能的)。

是否可以在成员初始化列表中未列出成员变量时禁用其默认构造函数?

最佳答案

您不能禁用构造。在到达构造函数的主体之前,必须初始化所有类成员。也就是说,您可以轻松解决该问题。您可以添加一个私有(private)静态成员函数,它获取 ab 并从中返回一个 LargeIntimidatingClass

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
    }
};

关于c++ - 在构造函数代码之前禁用默认类成员初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53962686/

相关文章:

c++ - 我的复制构造函数有什么问题?

c++ - 当默认构造函数充当默认参数时,它是如何工作的?

c++ - 成员初始化部分语句复杂?

c++ - 嵌套类。错误 : expected parameter declarator - for inner class instance

c++ - C++中动态数组的需要

c++ - 当引用的变量从外部更改时,使用对 const 的引用是否安全?

c++ - 从派生类访问静态常量变量

c++ - 使用继承类时处理构造函数

java - 是否可以在 java 中使用反射创建没有无参数构造函数的类的 'blank' 实例?

c++ - C++11 中的 "member initializer"是什么?