我一直在用包装在容器类中的引用弄乱。为什么下面的代码合法,并且看起来正确?
#include <iostream>
class Foo
{
public:
Foo( int i ) : i_( i ) {}
int i_;
};
class FooWrapper
{
public:
FooWrapper( Foo& foo ) : foo_( foo ) {}
Foo& foo_;
};
int main( int argc, char* argv[] )
{
Foo foo( 42 );
FooWrapper fw( foo );
FooWrapper fw2 = fw;
std::cout << fw2.foo_.i_ << std::endl;
return 0;
}
在没有显式
operator=
的情况下,我相信C++会进行成员复制。因此,当我执行FooWrapper fw2 = fw;
时,这不是两个操作:(1)使用默认的ctor创建FooWrapper fw
,然后(2)从fw
分配给fw2
吗?我确定这不会发生,因为无法创建未初始化的引用,所以fw2
的创建实际上被视为拷贝构造吗?有时我不清楚复制构造与分配的作用。就像在本例中一样,它们有时会相互渗出,但是可能有些规则我没有意识到。谢谢您的解释。
最佳答案
在下面的行中,您正在通过将其复制为fw2
来构造fw
。也就是说,您正在调用复制构造函数。
FooWrapper fw2 = fw;
示例
这是(online)示例,说明如何调用default constructor,copy constructor,copy assignment operator和move assignment operator(来自C++ 11)。
#include <iostream>
struct foo
{
foo() {std::cout << "Default constructor" << '\n';}
foo(foo const&) {std::cout << "Copy constructor" << '\n';}
foo& operator=(foo const&) {std::cout << "Copy assignment operator" << '\n'; return *this; }
foo& operator=(foo &&) {std::cout << "Move assignment operator" << '\n'; return *this; }
};
int main( int argc, char* argv[] )
{
foo a; // Default constructor
foo b = a; // Copy constructor
foo c; // Default constructor
c = b; // Copy assignment operator
b = std::move(c); // Move assignment operator
}