在调用基类的指针时,赋值运算符是否不会重载?

时间:2010-09-16 23:21:57

标签: c++ operator-overloading assignment-operator

我遇到了以下问题,向我证明我对C ++的工作知之甚少。

我使用带有纯虚函数的基类

class Base
    ...

和类型

的派生类
class Derived : public Base{
private:
  Foo* f1;
 ...

两者都实现了赋值运算符。除此之外,Derived的赋值运算符复制f1中的数据。在我的代码中,我创建了两个类Derived

的新实例
Base* d1 = new Derived();
Base* d2 = new Derived();

如果我现在调用赋值运算符

*d1 = *d2;

未调用Derived的赋值运算符,并且不复制f1中的数据!只有我这样做才有效。

*dynamic_cast<Derived*>(d1) = *dynamic_cast<Derived*>(d2);

有人可以解释为什么赋值运算符没有超载吗?

谢谢!

3 个答案:

答案 0 :(得分:4)

如果没有看到相关代码,很难说。这是一个有效的例子:

#include <iostream>

using namespace std;

class A {
  public:
    virtual A& operator=(A& a) {}
};

class B : public A {
  public:
    B& operator=(A& a) { cout << "B" << endl; }
};

int main() {
  A* foo = new B();
  A* bar = new B();
  *foo = *bar;
  return 0;
}

这将在运行时打印B

你可能做错的事情:

  1. 您可能忘记在基类中使operator=虚拟。
  2. 您可能已将孩子的班级operator=作为签名,比父母的operator=更具限制性,因此您实际上并未覆盖父级的定义。例如,如果您在上面的示例中将B& operator=(A& a) { cout << "B" << endl; }更改为B& operator=(B& a) { cout << "B" << endl; },则不会再打印B

答案 1 :(得分:3)

我对接受的答案有一些不同的看法。这基本上是More Effetive C++第33项。因此,即使已接受的解决方案有效,我认为重要的是要揭示使赋值算子虚拟化所涉及的危险!

class Animal {
public:
    virtual Animal& operator=(const Animal& rhs);
};

class Lizard: public Animal {
public:
    virtual Lizard& operator=(const Animal& rhs);
};

class Chicken: public Animal {
public:
    virtual Chicken& operator=(const Animal& rhs);
};

int main(){
    Lizard l;
    Chicken c;

    Animal *pL = &l;
    Animal *pC = &c;

    *pL = *pC;             // assigns chicken to a lizard.
}

答案 2 :(得分:1)

要使虚拟工作,您需要相同的签名。因此,如果operator= const Derived&类中的Derived参数与基类中const Base&参数上的operator=(const Base&)参数不匹配,则表示{。}}}。 p>

这意味着您可以完成多态,但是您需要在派生类中使用{{1}}来执行此操作。