类成员不是引用,而是带引用参数的构造函数

时间:2015-10-27 11:07:20

标签: c++ constructor pass-by-reference copy-constructor pass-by-value

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

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

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

b内的值是否已复制到a?或者,由于b是引用,因此b的引用已分配给a

6 个答案:

答案 0 :(得分:1)

这与以下代码完全相同:

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

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

答案 1 :(得分:1)

在班级定义

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

数据成员a不是参考。因此,在此构造函数中,数据成员由b引用的对象的值初始化。

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

另一方面,如果类被定义为

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

其中a是一个引用,然后在此构造函数中

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

a会引用b引用的对象。

答案 2 :(得分:0)

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

  

指定直接和虚拟基础子对象和非静态数据成员的初始化程序

修改

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

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

  

使用直接初始化,以初始化顺序执行对象基础和非静态成员的完整成员副本。

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

想想代码:

obj o;
foo f(o);

调用foo::foo时,参数会通过引用传递,因此{em} <\ n> 将<{1}}复制到参数o。然后:

b

由于成员变量foo::foo(b) : a(b) {} 未定义为引用,因此a将被复制到b,即a的副本将被调用。< / p>

答案 5 :(得分:0)

有时我会进入我的小型测试程序的方便的git repo并拉出我的对象生命跟踪器:

#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