C ++引用可以分配吗?

时间:2017-08-04 07:37:53

标签: c++ reference variable-assignment copy-constructor assignment-operator

我一直在搞乱容器类中包含的引用。为什么以下代码合法且看起来行为正确?

#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)从fwfw2的分配?我确信这不会发生,因为无法创建未初始化的引用,所以fw2的创建实际上被视为复制构造吗?

我有时不清楚复制构造与作业的作用;它们似乎有时会相互渗透,就像在这个例子中一样,但可能有一些我不知道的规则。我很感激解释。

3 个答案:

答案 0 :(得分:4)

尽管语法中有FooWrapper fw2 = fw;fw2复制构造FooWrapper(使用复制构造函数)。根本不涉及默认构造或分配。

要回答标题中的问题:不,不能分配引用。如果您编写了试图实际默认构造或分配FooWrapper fw2; fw2 = fw; 的代码,例如:

{{1}}

......这会失败。官方说来,只有一个&#34;诊断&#34;是必须的。非正式地,我所知道的每个编译器都会拒绝编译它。

答案 1 :(得分:3)

这个初始化实际上调用了复制构造函数。 FooWrapper fw2 = fw; 并相当于 FooWrapper fw2(fw);

隐式定义的复制构造函数不需要创建未初始化的引用

供参考: http://en.cppreference.com/w/cpp/language/copy_constructor

答案 2 :(得分:3)

在下面的一行中,您将fw2复制为fw。也就是说,您正在调用复制构造函数。

FooWrapper fw2 = fw;

示例

以下是onlinedefault constructorcopy constructorcopy assignment operator(来自C ++ 11)的调用示例(move assignment operator)。

#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
}