【问题标题】:Value initialization值初始化
【发布时间】:2014-06-02 10:51:43
【问题描述】:

$8.5/7 声明

——如果 T 是一个(可能是 cv 限定的)非联合类类型,没有用户提供的构造函数,那么对象 是零初始化的,如果 T 的隐式声明的默认构造函数是非平凡的,则该构造函数是 调用。

我无法理解这句话的最后一部分“如果 T 的隐式声明的默认构造函数不平凡,则调用该构造函数。”

有人可以举个例子解释一下吗?

class A
{
    int x;
};

class B : A {};

B b{};

我认为上面代码中的B 有一个重要的构造函数。但是如何观察对B 隐式声明的构造函数的调用并确保我的编译器正在调用它?

【问题讨论】:

  • 为什么你认为B 有一个不平凡的构造函数?它满足 C++11 12.1/5 中给出的普通构造函数的所有条件。

标签: c++ c++11 language-lawyer


【解决方案1】:

我认为上面代码中的 B 有一个非平凡的构造函数。

在您的示例中,构造函数很简单。

查看 C++11 12.1/5 中的条件,这两个类都没有用户声明的构造函数、虚函数、虚基类、带有初始化器的成员或类类型的成员; A 没有基类,B 只有一个普通的基类。

但是我如何观察对 B 隐式声明的构造函数的调用并确保我的编译器正在调用它?

使用隐式但不平凡的默认构造函数创建类的一种方法是拥有不平凡的成员或基类:

struct A {
    // A user-declared constructor is non-trivial
    A() {std::cout << "Construct A\n";}
};

struct B : A {};

现在你可以(间接地)观察被调用的B的隐式构造函数,通过观察它调用A的构造函数时的副作用。

【讨论】:

    【解决方案2】:

    N3797之后的解释:

    一个函数是用户提供的,如果它是用户声明的而不是明确的 在第一次声明时默认或删除。

    因此,由于您没有为B 声明默认构造函数,因此它不是用户提供的。 以下适用:

    如果默认构造函数不是用户提供的并且如果:

    ——它的类没有虚函数 (10.3) 也没有虚基 类 (10.1) 和

    ——其类的非静态数据成员没有 brace-or-equal-initializer,和

    ——其类的所有直接基类都具有平凡的默认值 构造函数,以及

    ——对于它的类中所有属于类的非静态数据成员 类型(或其数组),每个这样的类都有一个微不足道的默认值 构造函数。

    所以这确实是微不足道的,因为我们可以对A 递归地应用相同的过程。

    其他例子:

    struct A { A() = default; }; // Trivial default constructor!
    struct A { A() = delete; }; // Also trivial!
    struct A { A(); }; // Can't be trivial!
    
    struct B { virtual void f(); }
    struct A : B {}; // Non-trivial default constructor.
    
    struct B {};
    struct A : virtual B {}; // Non-trivial default constructor.
    

    【讨论】:

      【解决方案3】:

      想象一下你有这个

      struct A {
        string a;
        int value;
      };
      
      int main() {
        A a = A();
        return a.value;
      }
      

      a.value 在我们返回该值时为零,因为该对象是零初始化的。但这还不够,因为a 还包含一个具有构造函数的字符串成员。对于要调用的构造函数,标准安排调用A 的构造函数,这最终将导致构造成员。

      【讨论】:

        猜你喜欢
        • 2014-12-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-08
        • 1970-01-01
        • 1970-01-01
        • 2021-06-03
        • 1970-01-01
        相关资源
        最近更新 更多