赋值运算符(=
)是否必须始终将rvalue复制到左值中,还是完全依赖于它操作的操作数类型?对不起,如果它是愚蠢的,但无论我读到什么,都会写出它只是将右边的值复制到左边。我想把事实弄清楚。
请举例说明C ++。
答案 0 :(得分:2)
它完全取决于你如何实现赋值运算符和类的组合......在C ++中,POD类或结构的默认编译器创建的赋值运算符方法将只执行逐位复制将RHS对象放入LHS对象中,但用户定义的赋值运算符可以执行您想要的任何操作。它将始终属于LHS对象,但它不需要进行任何复制,或者如果您愿意,可以有任意数量的副作用。
答案 1 :(得分:2)
您可以随意重载赋值运算符,但C ++中的常规实现是这样的:
class MyObject
{
public:
MyObject& operator=(const MyObject& rhs)
{
if (this != &rhs)
x = rhs.x;
return *this;
}
private:
int x;
};
这样做的原因是允许简单分配自定义对象。由于用户定义的类和结构有时很复杂,因此需要提供自定义赋值运算符来执行指针成员的深层复制等操作。
MyObject a;
MyObject b;
b = a; // calls assignment operator b.operator=(a);
请注意,您不能在C和Java中重载运算符,可能会采用不同的方式。
修改强>
Griwes指出,您可能想知道的其他事情是,如果您没有指定一个,则编译器将为您的用户定义对象生成一个隐式赋值运算符。有时您只想定义或声明它以避免编译器生成的默认行为。
还有一些=
令牌的用法实际上会调用复制构造函数,例如,如果您修改我之前的用例,如下所示:
MyObject a;
MyObject b = a; // this calls the copy constructor (also implicitly defined if not provided)
它可能看起来像一个赋值,但在上面的情况下不会调用自定义提供的运算符。如果您在执行或不想定义赋值运算符时有更多原因,请查看维基百科上的三条规则。
答案 2 :(得分:2)
赋值运算符(=)是否必须始终将rvalue复制到左值。
没有。对于用户定义的类型,它没有这样的东西。相反,它调用适当的operator=
函数。考虑这些类:
#include <iostream>
struct Half {
int i;
void operator=(int j) { i = j/2; }
};
struct Double {
int i;
void operator=(int j) { i = j*2; }
};
int main () {
Half h;
h = 3;
Double d;
d = 3;
std::cout << h.i << " " << d.i << "\n";
// Result is "1 6"
}
如您所见,赋值运算符可以自由执行它认为合适的任何操作。在这种情况下,它显然不仅仅是一个“副本”。
答案 3 :(得分:0)
不同的语言使用不同的概念
Java和C ++以及C +是的,这是一个赋值,除非被另一个函数重载
T-SQL =成为测试和作业
答案 4 :(得分:0)
复制过于笼统。
在C中,如果指定指针,则不会复制实数值,但会保存存储右侧操作数的存储器地址。
int *ptr = (int *)malloc(sizeof(int *));
*ptr = 1; // points at whatever address 1 has
ptr = 1; // points at address 1, containing ????