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
当你在 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