提问人:StoneThrow 提问时间:8/4/2017 最后编辑:JonasStoneThrow 更新时间:8/4/2017 访问量:836
C++ 引用可以分配吗?
C++ reference can be assignable?
问:
我一直在搞砸包装在容器类中的引用。为什么以下代码是合法的,并且看起来行为正确?
#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;
}
在没有明确的 的情况下,我相信 C++ 会做一个成员复制。所以当我这样做时,这不是两个操作吗:(1) 使用默认的 ctor 创建,然后是 (2) 从 到 的赋值?我确定这不会发生,因为引用不能在未初始化的情况下创建,那么创建实际上是否被视为复制构造?operator=
FooWrapper fw2 = fw;
FooWrapper fw
fw
fw2
fw2
我有时不清楚文案构建与分配的作用;它们有时似乎会相互渗透,就像在这个例子中一样,但可能有一些我不知道的规则。我将不胜感激。
答:
尽管在语法中,copy 构造(使用 copy 构造函数)。既不涉及默认构造,也不涉及赋值。=
FooWrapper fw2 = fw;
fw2
并回答标题中的问题:不,不能分配参考文献。如果您编写的代码试图实际默认构造或赋值 ,例如:FooWrapper
FooWrapper fw2;
fw2 = fw;
...这将失败。正式地,只需要“诊断”。非正式地,我所知道的每个编译器都会/将拒绝编译它。
此初始化实际上调用复制构造函数。 并等同于FooWrapper fw2 = fw;
FooWrapper fw2(fw);
隐式定义的复制构造函数不需要创建未初始化的引用
供参考:http://en.cppreference.com/w/cpp/language/copy_constructor
评论
implicitly defined copy constructor
default
class_name ( const class_name & ) = default;
在下面的一行中,您通过使它成为 的副本来构造。也就是说,您正在调用 copy-constructor。fw2
fw
FooWrapper fw2 = fw;
例
下面是一个(在线)示例,说明如何调用默认构造函数、复制构造函数、复制赋值运算符和移动赋值运算符(来自 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
}
评论