超类的重载赋值运算符

时间:2014-03-22 08:29:14

标签: c++ class

所以问题如下:

我们有这样的课程:

    class Boo : public SuperBoo {

Foo* fFoo1;

Foo* fFoo2;

// ...

}

,其中foo是一个单形类。现在我们需要为这个类重载赋值运算符(=)。

3 个答案:

答案 0 :(得分:2)

class derived : public base {
    public:
        double *b;
        derived(double aParam, double bParam) : base(aParam) { 
            b = new double; *b = bParam; 
        }
        derived() : base() { 
            b = new double; *b = 0; }
        ~derived() { 
            delete b; 
        }
        derived(const derived &derivedParam) : base(derivedParam) { 
            b = new double; *b = *derivedParam.b; 
        }
        void show() { 
            cout << *a << " " << *b << endl; 
        }
        derived &operator=(const derived& derivedParam) { 
            *a = *derivedParam.a; *b = *derivedParam.b; return *this; 
        }
};

int main(){
    base *ptrB1, *ptrB2;
    derived objD1(5,6), objD2;
    ptrB1 = &objD1;
    ptrB2 = &objD2;
    *ptrB2 = *ptrB1;
    ptrB2->show();

    return 0;
}

答案 1 :(得分:1)

由于你有两个指针作为数据成员,你需要有一个重载的赋值运算符(以及一个析构函数和一个复制构造函数),以便在赋值的情况下制作指针的深层副本

Boo::operator=( const Boo& obj) {
      Superboo::operator=obj //calling the assignment operator of the base explicitly
      fFoo1 = obj->fFoo1;
      fFoo2 = obj->fFoo2;
      return *this;
  }

现在,由于Boo继承自SuperBoo,您必须显式调用基类Superboo的赋值运算符(如果为其定义了非默认赋值运算符。)

答案 2 :(得分:1)

通常,当您拥有类层次结构时,通常谨慎不提供赋值运算符。事实上,通常最好防止分配和复制构造:

class Example
{
    // ...
private:
    Example(Example const &);
    Example &operator=(Example const &);
};

或者在C ++ 11中:

class Example
{
    // ...
    Example(Example const &) = delete;
    Example &operator=(Example const &) = delete;
};

赋值运算符通常用于值类,而不适用于具有标识的类。在你的例子中,名字并没有告诉我们什么,真的。但是,如果您的Boo实际上类似于GuiWidgetDriverFileStreamThreadWrapper,即面向对象编程实际上可能有用的东西,那么任务的概念不再有意义。将一个GuiWidget分配给另一个GuiWidget是什么意思,或者为了更精确的示例,将一个按钮分配给下拉菜单是什么意思?

分配对于未引用其他资源的类非常有用,例如MatrixColorListPostalAddress。将一个Matrix分配给另一个Matrix或者将蓝色对象分配给红色对象当然是有意义的。

查看标准库。您会注意到像std::ifstream这样的面向对象的类不支持赋值,而像std::list这样的值类则支持赋值。

您希望支持面向对象类的分配可能有以下两个原因之一:

  1. 你想支持赋值,因为“它很自然,每个C ++类都应该拥有它”。那是错的。

  2. 当你“分配”时,你想要一些特殊的东西。在上面的示例中,当向下拉菜单“分配”按钮时,您可能只想给下拉菜单提供与按钮相同的颜色。这是一个有效的愿望,但operator=只是一个错误的(即误导性的,令人困惑的)函数名称。你最好将这个函数命名为AssignStyleFrom,并禁止赋值。

  3. 通过阻止面向对象类的分配,您还可以避免所有令人讨厌的问题以及随之而来的混乱。在Scott Meyers的 Effective C ++ (或者它是更有效的C ++ ?)中,有一整章关于类层次结构中赋值运算符的缺陷。通过设计程序使得赋值运算符仅由不可导出的值类提供,您不再需要担心这些事情。