Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 类成员不是引用,而是通过引用传递参数的构造函数_C++_Constructor_Pass By Reference_Copy Constructor_Pass By Value - Fatal编程技术网

C++ 类成员不是引用,而是通过引用传递参数的构造函数

C++ 类成员不是引用,而是通过引用传递参数的构造函数,c++,constructor,pass-by-reference,copy-constructor,pass-by-value,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?,这与以下代码相同: void foo(obj& b) { obj a(b); } 它将b对象复制(复制构造)到您正在查看的a,其中: 指定直接和虚拟基子对象以及非静态数据成员的初始值设定项 编辑: 在内部,这只是a,

如果在C++中有类似的内容,会发生什么情况:

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

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

b
中的值是否复制到
a
?或者由于
b
是引用,那么
b
的引用被分配给
a

,这与以下代码相同:

void foo(obj& b) {
    obj a(b);
}
它将
b
对象复制(复制构造)到您正在查看的
a
,其中:

指定直接和虚拟基子对象以及非静态数据成员的初始值设定项

编辑:

在内部,这只是
a
,在
类obj
中定义为:
obj(obj&)
obj(const obj&)

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

使用直接初始化,按初始化顺序对对象的基本成员和非静态成员执行完整的成员复制


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


然而,在构造函数中,效果是
obj a=b调用
obj
上的副本构造函数。

在类定义中

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
引用的对象

想想代码:

foo::foo(b) : a(b) {}
obj o;
foo f(o);
调用
foo::foo
时,参数通过引用传递,因此
o
不会复制到参数
b
。然后:

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

由于成员变量
a
未定义为引用,因此
b
将被复制到
a
,即调用
obj
的copy-ctor。

正是在这种情况下,我会进入我手边的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;
}

如果您的代码被修复为实际可编译,那么是的,
a
将是
b
的副本。我的问题是内部会发生什么?b的值是否复制到a?还是仅仅是一个参考任务?@mkmostafa抱歉我误解了这个问题。我已经给出了一个链接,并添加了有关复制构造函数的功能的相关文本。顺便说一句,花点时间研究一下C++11中介绍的那些可能也是值得的。b中的所有值是否都复制到a?@mkmostafa,这取决于
obj
的复制构造函数是如何实现的。有没有办法更新我的代码,使b通过引用分配给a?@mkmostafa,为什么不将
a
声明为引用呢?因为我想自由地将其保留为NULL,或者稍后对其进行初始化。引用成员不允许这样做。因此,最终将b的值复制到a?是
a
通过调用复制构造函数(
obj::obj(const&rhs)
)进行初始化。这是在初始化
a
时,使用
obj a(b)调用它是的,问题是我不想有一个类成员作为引用,因为它带来的限制。我希望两者兼而有之,以便能够在任何时候同时初始化成员。如果我传递了对对象的引用,我不希望复制整个值!我还想避免使用指针!:D