我一直在用包装在容器类中的引用弄乱。为什么下面的代码合法,并且看起来正确?

#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 constructorcopy constructorcopy assignment operatormove 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
}

09-06 19:16