不同类型操作数的赋值运算符

时间:2012-06-19 21:01:13

标签: c++ assignment-operator

赋值运算符(=)是否必须始终将rvalue复制到左值中,还是完全依赖于它操作的操作数类型?对不起,如果它是愚蠢的,但无论我读到什么,都会写出它只是将右边的值复制到左边。我想把事实弄清楚。

请举例说明C ++。

5 个答案:

答案 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 ????