构造函数初始值设定项列表与构造函数体

时间:2021-05-06 05:09:48

标签: c++ constructor

假设 someString 初始化有点复杂,因此我们编写了一个简单的成员函数 stringInitialization() 来初始化 someString构造函数体:

class DemoL {
private:

    int someNumber;
    std::string someString;

    void stringInitialization() {
        if (someNumber == 1) {
            someString = "FIRSTSTRING";
        } else if (someNumber == 2) {
            someString = "SECONDSTRING";
        } else {
            someString = "";
        }
    }

public:
    explicit DemoL(int rNumber) :
            someNumber(rNumber) {
        stringInitialization();
    }
};

这样,我假设 someString 将在构造函数主体之前默认初始化,只有在此之后才会通过调用 stringInitialization() 进行修改。

那么,让我们稍微修改一下代码,以便我们在构造函数初始化列表中初始化someString

class DemoL {
private:

    int someNumber;
    std::string someString;

    std::string stringInitialization() const {
        if (someNumber == 1) {
            return "FIRSTSTRING";
        } else if (someNumber == 2) {
            return "SECONDSTRING";
        } else {
            return "";
        }
    }

public:
    explicit DemoL(int rNumber) :
            someNumber(rNumber),
            someString(stringInitialization()) {}
};

你能不能告诉我第二种变体是否更有效和正确?

1 个答案:

答案 0 :(得分:1)

你的假设是正确的。构造函数 DemoL(int rNumber) 需要能够默认构造成员 someString,这没有问题,因为 std::string 是默认可构造的。

显而易见的一点是,一个成员可能不是默认构造的,在这种情况下,您将必须初始化它。

但即使是这样,默认构建它也可能会浪费资源,如果您在之后立即更改它,那么第二种选择对我来说似乎更好,因为它直截了当。

但是,由于 stringInitialization 按值返回,我会使用 std::move,不,正如评论中指出的那样,这实际上是一个坏主意。

总结:

  • 这两个代码在 someNumber 方面是相同的
  • 第一个代码默认初始化someString(“调用”std::basic_string<...>::basic_string),然后分配它(调用std::basic_string<...>::operator=
  • 当对 std::string 的调用返回(调用 stringInitialization)时,第二个代码从字符串文字构造返回 basic_string<...>::basic_string(const char*) 值,然后复制构造 someString(调用basic_string<...>::basic_string(basic_string&&));实际上复制省略发生是因为 stringInitialization 返回一个右值。