在子类上重载

时间:2011-08-08 11:55:51

标签: c++ operator-overloading

我有一个类的层次结构,我必须重载operator+operator-,以便它生成一个类似的新类型。

Animal * pg = new Pigeon();
Animal * pgone = new Pigeon();

Animal * babypigeon = *pgone + *pg;

其中Animal是基本类型,Pigeon是派生类型。我想知道我是否应该重载派生类型的运算符,还是我还需要重载基类型的运算符?

假设将使用基指针创建所有派生类型。

4 个答案:

答案 0 :(得分:3)

您的逻辑已关闭,您的程序将无法执行您期望的操作。你在那里添加指针。不会调用+运算符。

你需要像

这样的东西
babypigeon = (*pgone) + (*pg);

在这种情况下,您要添加两个动物。所以你的+运算符必须在Animal类中重载。

解决这个问题的方法是从+运算符调用一些虚方法并在那里使用逻辑。

编辑:

class Animal{
//....
    virtual Animal plusLogic( const Animal& otherAnimal ) const;
    Animal operator + ( const Animal& otherAnimal ) const
    {
        return this->plusLogic(otherAnimal);
    }
}

class Pigeon : public Animal{
//.....
    virtual Animal plusLogic( const Animal& otheAnimal ) const;
}
Animal Pigeon::plusLogic (const Animal& otherAnimal) const
{
    //logic heree
}

这样,在一个类型为pigeon的Animal上调用+运算符将调用Pigeon类中的函数plusLogic(因为它是虚拟的)。

答案 1 :(得分:2)

你不能这样做 - pgonepg是指针类型,并且不能让运算符为它们重载。你必须有

Animal* baby = *pgone + *pg;

在这种情况下,您需要一个双重调度系统来涵盖所有案例,我也希望您永远不要将这些类型用作值。我希望你也没有太多衍生类型,因为这可能会很快变得讨厌。

答案 2 :(得分:1)

  • 您可能不会为指针类型重载运算符,因此您的代码不应该编译(编辑:问题已被修改且不应编译部分不再有效),

  • 一般运算符重载最好用非多态类型:

    • 见上面的限制,
    • 有多态类型,你经常需要多个distpatch来做一些有意义的事情
    • 返回多态值有其自身的问题(如果需要分配内容,谁是所有者),由于运算符驱动要合并(a+b+c
    • 而增加
    • 一个潜在的解决方案是字母/ enveloppe成语

答案 3 :(得分:1)

我看到这种方法有几个非常基本的问题:

  1. 对于交配鸽子没有普遍认可的操作员(实际上,使用*而不是+表示不是更好吗?),所以这显然 < em>违反first basic rule of operator overloading 虽然@Alexandre开了个玩笑,但他的评论确实有一个好处:而是使用 名称齐全的函数

  2. 运算符重载是 非常适合值类型 ,而 不适合多态类型 < / strong>即可。交配任何两只动物都没有任何意义 您不能一般性地指定结果的(动态)类型,因为您必须为每个排列创建一个新类型,从而创建甚至新的可能排列,从而导致类型无穷无尽的扩散。 (如果你尝试的话,你也可以跟着动物保护联盟,而且它们可能非常烦人。)

  3. 您的示例使用的运算符通过引用获取两个对象,但必须返回指向动态分配对象的指针。这不仅听起来非常错误,而且也是如此 对于初学者:现在你不能再加链(pg1 + pg2 + pg3,因为加法的结果与它的操作数不是同一类型。这是违反直觉的, 违反了the second basic rule of operator overloading 即可。
    我甚至不会触及诸如谁拥有退回物品以及谁负责清理它等问题。

  4. 所以结果是: 就是不要这样做。 而且我没有发现这令人惊讶,因为多年来我了解到这是如果您尝试在此类设置中应用运算符重载,则通常会产生结果。