构造函数销毁成员变量

Constructor destroys member variables

为什么第二次调用构造函数时初始化的成员变量被删除?

示例:

class MyClass {
    private:
        unsigned myValue;

    public:
        MyClass(void)
        {
            this->myValue = 1337;

            fprintf(stderr, "myValue: %d\n", this->myValue);
        }

        MyClass(int myFirstValue)
        {
            fprintf(stderr, "myValue: %d\n", this->myValue);
        }
};

int main()
{
    /* Constructor is called */
    MyClass myInstance;

    /* Call other constructor ; myInstance->myValue is now trashed */
    myInstance = 100;

    return 0;
}

输出:

myValue: 1337
myValue: 1606416392

预期输出:

myValue: 1337
myValue: 1337

有没有办法保留初始化的成员变量?

当你这样做时

myInstance = 100;

使用构造函数 MyClass(int) 在 RHS 上构造临时 MyClass。然后使用临时变量为 LHS 赋值。

那个构造函数没有初始化成员变量。读取未初始化的成员会导致 未定义的行为 ,在您的情况下,这似乎会导致打印垃圾值。

你需要这样初始化它,假设你想将成员初始化为构造函数中传递的值:

MyClass(int myFirstValue) : myValue(myFirstValue)
{
  // as before
}

编辑 因为您希望成员的值为 1337,所以您需要

MyClass(int myFirstValue) : myValue(1337) { .... }
myInstance = 100;

是对函数的调用MyClass& MyClass::operator=( MyClass const &other)

但因为您没有实现它,所以调用了 default 赋值运算符。如您所见,此函数将 MyClass 引用作为参数。这意味着整数文字 1 100 必须转换为 MyClass。 C++ 实现可以自由地进行这样的隐藏、用户定义 转换。它在这种情况下做到了。因为您没有在 MyClass(int myFirstValue) 中初始化整数成员,所以 默认初始化 2 发生了。对于 int 变量,这意味着没有初始化和 未确定的 值。然后您尝试读取并将此未定义的值分配给您的原始对象。这会导致未定义的行为,因此从现在开始,您的程序的行为是未定义的、不确定的。

您可以限制构造函数仅使用单词 explicit 显式调用并解决初始化整数成员的问题:

MyClass( int myFirstValue) : myValue( myFirstValue)
{
    //.... 
}

C++ 标准 n3337 § 12.3 转换

1) Type conversions of class objects can be specified by constructors and by conversion functions. These conversions are called user-defined conversions and are used for implicit type conversions (Clause 4), for initialization (8.5), and for explicit type conversions (5.4, 5.2.9).

2) User-defined conversions are applied only where they are unambiguous (10.2, 12.3.2). Conversions obey the access control rules (Clause 11). Access control is applied after ambiguity resolution (3.4).

3) [ Note: See 13.3 for a discussion of the use of conversions in function calls as well as examples below. — end note ]

4) At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.

1 C++ 标准 n3337 § 2.14.2 文字 1) 整数文字是没有句点或指数部分的数字序列。整数文字可能有 指定其基数的前缀和指定其类型的后缀。序列的词法第一个数字 的数字是最重要的。十进制整数文字(以十为基数)以 0 以外的数字开头,并且 由一系列十进制数字组成。八进制整数文字(以八为基数)以数字 0 开头, 由一系列八进制数字组成。22 十六进制整数文字(基数为十六)以 0x 或 0X 开头, 由一系列十六进制数字组成,其中包括十进制数字和字母 a 到 f 以及 A 到 F,十进制值为 10 到 15。 [ 例子:数字十二可以写成 12, 014 或 0XC。 — 结束示例]

2 C++ 标准 n3337 § 8.5 初始化器 6) 默认初始化类型 T 的对象意味着: — 如果 T 是(可能是 cv 限定的)class 类型(第 9 条),则调用 T 的默认构造函数(并且 如果 T 没有可访问的默认构造函数,则初始化格式错误); — 如果 T 是数组类型,则每个元素都是默认初始化的; — 否则,不执行初始化。 如果程序要求默认初始化 const 限定类型 T 的对象,则 T 应为 class 使用用户提供的默认构造函数键入。