C++ 类成员不是引用,而是通过引用传递参数的构造函数
如果在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,
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