比方说,我有A类,带有内部指针。我声明变量:
A a;
A b;
A&c;
我希望“ a = b”(或“ b = a”)进行深度复制,但我希望“ c = a”(或“ c = b”)充当参考并反映变化将来做成a或b。
我本以为c的浅表复制/引用行为是自动的,但是我认为我的赋值运算符可能过载得很差,因为当我说“ c = a”时它仍然被调用,并且仍然进行深表复制。 / p>
现有的赋值运算符签名为:A&运算符=(const A&a);
我如何具有重载的赋值运算符以进行深度复制,但如何保持类似引用的引用行为?
答案 0 :(得分:3)
这不是引用在c ++中的工作方式。引用仅在声明时绑定到另一个变量。实际上,这段代码
A& c;
甚至不会编译。您必须将其绑定到其他变量,例如:
A& c = a; // does not call operator= (no deep copy)
但是,在这之后,如果您执行c
,则分配给c = b;
会调用副本分配运算符,这会进行深度复制。请注意,由于c
已绑定到a
,所以这与将b
分配给a
相同。
答案 1 :(得分:3)
C ++希望引用的行为就像引用所绑定的对象的另一个名称一样。它明确地不希望用户能够重新绑定引用,以使绑定的引用引用另一个对象。
这样,如果a
是对c
的引用,那么a
的每次使用都将与您使用std::reference_wrapper
时的行为完全相同(有一些小例外,没有其中适用于您的使用)。您不能“保持类似参考的行为;”这根本不是语言功能的目的。
您想要的是一个指针(或c = &a
,但是指针通常是您想要的)。这样,您可以区分重新绑定操作(*c = a
)和值分配操作({{1}})。
答案 2 :(得分:1)
A&c;
这不是我们在C ++中定义reference变量的方式。参考应该是 在定义时绑定到对象。创建之后,便无法将它们更改为指向其他内容。
正确的方法:
A&c = a;
对于以上几点,没有调用构造函数。只是c
被用作对象a
的别名。但是,如果您执行c = b
,则将调用对象copy assignment
和a
的{{1}},如下所示。
我本以为c的浅表复制/引用行为是自动的,但是我认为我的赋值运算符可能过载得很差,因为当我说“ c = a”时它仍然被调用,并且仍然进行深表复制。 / p>
b
调用对象c = a
和a
的副本构造函数。 C ++中的Pointer对您来说是更好的选择。可以更改它们以指向任何对象。请参见下面的示例,了解我在b
函数中的指针的示例,并且它执行main
复制(请参见未调用任何构造函数或赋值运算符)。
显示哪个对象被调用的示例:
shallow
输出:
#include <iostream>
class A {
public:
A(void)
{
std::cout << "__CONSTRUCTOR__" << std::endl;
std::cout << this << std::endl;
}
A(const A& )
{
std::cout << "__COPY_CONSTRUCTOR__" << std::endl;
std::cout << this << std::endl;
}
const A& operator=(const A& other)
{
std::cout << "__COPY_ASSIGNMENT__" << std::endl;
std::cout << this << " and " << &other << std::endl;
return *this;
}
~A(void)
{
std::cout << "__DESTRUCTOR__" << std::endl;
std::cout << this << std::endl;
}
};
int main(void)
{
std::cout << "Example with reference" << std::endl;
std::cout << "------------ CREATING A ------------" << std::endl;
A a;
std::cout << "------------ CREATING B ------------" << std::endl;
A b;
std::cout << "------------ CREATING C ------------" << std::endl;
A& c = b;
std::cout << "-------------- C = A ---------------" << std::endl;
c = a;
std::cout << std::endl;
std::cout << std::endl;
std::cout << "Example with pointers" << std::endl;
std::cout << "------------ CREATING D ------------" << std::endl;
A *d;
std::cout << "-------------- D = &A --------------" << std::endl;
d = &a;
std::cout << "-------------- D = &B --------------" << std::endl;
d = &b;
std::cout << std::endl;
std::cout << std::endl;
std::cout << "Leaving the program" << std::endl;
}