Class 成员不是引用而是参数通过引用传递的构造函数

Class Member Not a Reference but Constructor with Argument Passed by Reference

当你在 C++ 中有这样的东西时会发生什么:

class foo {
public:
   foo(obj &b);
   obj a;
};

foo::foo(b) : a(b) {}

是否将 b 中的值复制到 a?或者既然b是reference,那么b的reference赋值给a?

这与以下代码相同:

void foo(obj& b) {
    obj a(b);
}

它将 b 对象复制(复制构造)到 a

您正在查看 constructor initializer list,其中:

Specifies the initializers for direct and virtual base subobjects and non-static data members

编辑:

在内部这只是 copy constructs a,它在 class obj 中定义为:obj(obj&)obj(const obj&).

如果 obj 没有用户定义的构造函数 编译器将 implicitly declare a copy constructor 将:

Performs full member-wise copy of the object's bases and non-static members, in their initialization order, using direct initialization.

复制发生obj & b允许传入对象的引用,保存一个副本。

但是在构造函数中,效果是 obj a = b; 调用了 obj 上的复制构造函数。

在class定义中

class foo {
   foo(obj &b);
   obj a;
};

数据成员a 不是引用。所以在这个构造函数中,数据成员由 b.

引用的对象的值初始化
foo::foo(b) : a(b) {}

另一方面,如果 class 定义为

class foo {
   foo(obj &b);
   obj &a;
};

其中 a 是此构造函数中的引用

foo::foo(b) : a(b) {}

a 将引用 b.

反过来引用的对象

想想代码:

obj o;
foo f(o);

调用 foo::foo 时,参数通过引用传递,因此 o 不会 被复制到参数 b。然后:

foo::foo(b) : a(b) {}

因为成员变量a没有定义为引用,所以b会被复制到a,即会调用obj的copy ctor .

有时就是这样,我会打开我手边的 git 小测试程序库,然后取出我的对象生命周期跟踪器:

#include <iostream>
#include <string>

using namespace std;

struct A {
    A()
    {
        cout << "Created " << describe() << endl;
    }

    A(A&& r)
    : ident(r.ident)
    {
        r.zombie = true;
        cout << "Move-constructed " << describe() << endl;
    }
    A(const A& r)
    {
        cout << "copy-constructed " << describe() << " from " << r.describe() << endl;
    }
    ~A() {
        cout << "destroyed " << describe() << endl;
    }

    A& operator=(A&& r) {
        cout << describe() << " is being move-assigned from " << r.describe() << endl;
        ident = r.ident;
        zombie = false;
        r.zombie = true;
        return *this;
    }
    A& operator=(const A&r ) {
        cout << describe() << " is being assigned from " << r.describe() << endl;
        zombie = false;
        return *this;
    }

    string describe() const {
        return (zombie ? "zombie "s : "object "s) + to_string(ident);
    }

    size_t ident = next_ident();
    bool zombie = false;

    static size_t next_ident() {
        static size_t ident = 0;
        return ident++;
    }
};


class foo {
public:
    foo(const A &b) : a(b) {}
    foo(A &&b) : a(move(b)) {}
    A a;
};

auto main() -> int
{
    A a;
    foo f(a);
    foo f2(move(a));
    A a2;
    f = a2;
    f2 = move(a2);

    return 0;
}

示例输出:

Created object 0
copy-constructed object 1 from object 0
Move-constructed object 0
Created object 2
copy-constructed object 3 from object 2
object 1 is being move-assigned from object 3
destroyed zombie 3
Move-constructed object 2
object 0 is being move-assigned from object 2
destroyed zombie 2
destroyed zombie 2
destroyed object 2
destroyed object 3
destroyed zombie 0