繁体   English   中英

默认复制/移动构造函数中的默认成员变量

[英]Default member variables in defaulted copy/move constructors

在默认复制/移动构造期间,具有默认值的成员变量究竟发生了什么? 如此:

struct A {bool a = true;};

A x;
x.a = false;
A y = x;

我可以想象几种不同的工作方式,等效地写为

struct A {bool a;}; //no default

//option 1
A::A(const A& other) noexcept : a(other.a) {}

//option 2
A::A(const A& other) noexcept : a(true) {a = other.a;}

//option 3
A::A(const A& other) noexcept {a = other.a;}

//option 4 (hopefully not)
A::A(const A& other) noexcept : a(true) {}

除了明显的例外,使用这些会使 A 不是TriviallyCopyable

构造函数必须并且将始终初始化所有 class 数据成员。

默认初始化器将用于未显式初始化该数据成员的构造函数。 默认复制构造函数将使用来自复制的 object 的相应数据成员的副本初始化每个数据成员,因此不会使用默认初始化程序。

这会导致在复制构造函数中使用默认初始值设定项(如果它是用户提供的并且缺少该成员初始值设定项)的情况(感谢 NathanOliver 指出这一点)。

例如:

A(whatever param) {}            // default initializer used
A(whatever param) : a{true} {}  // default initializer NOT used
A(const A&) = default;          // default initializer NOT used
A(const A&) : a{other.a} {}     // default initializer NOT used
A(const A&) {}                  // default initializer used

快速测试,我们将看到A的默认Loud成员是如何在A的默认复制构造函数期间初始化和复制的:

#include <iostream>
struct Loud {
    Loud(bool a) : b(a) {
        std::cout << "ctr with value " << b <<std::endl;
    }
    Loud(const Loud& other) noexcept : b(other.b) {
        std::cout << "cpyctr with value " << b << std::endl;
    }
    Loud& operator=(const Loud& other) noexcept {
        b = other.b;
        std::cout << "cpyasn with value " << b << std::endl;
        return *this;
    }
    bool b;
};
struct A {Loud a = true;};
int main(int argc, char** argv) {
    A x;         //1
    x.a = false; //2
    A y = x;     //3
    return 0;
}

-O0 ,产生:

ctr with value 1    //1 (constructing x)
ctr with value 0    //2 (implicit conversion from `false`)
cpyasn with value 0 //2 (assigning to x)
cpyctr with value 0 //3 (constructing y)

这意味着A的默认构造函数的行为与

//option 1
A::A(const A& other) noexcept : a(other.a) {}

这支持另一个答案(具有默认值的成员)没有任何可见的效果

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM