【问题标题】:Comparing objects and inheritance比较对象和继承
【发布时间】:2010-05-13 08:49:51
【问题描述】:

在我的程序中,我有以下类层次结构:

class Base // Base is an abstract class
{
};

class A : public Base
{
};

class B : public Base
{
};

我想做以下事情:

foo(const Base& one, const Base& two)
{
  if (one == two)
  {
    // Do something
  } else
  {
    // Do something else
  }
}

我有关于 operator==() 的问题。当然比较AB 的实例是没有意义的,但是比较Base 的两个实例应该是可能的。 (你不能比较狗和猫,但是你可以比较两种动物)

我想要以下结果:

A == B => false

A == A => truefalse,取决于两个实例的有效值

B == B => truefalse,取决于两个实例的有效值

我的问题是:这是一个好的设计/想法吗?这甚至可能吗?我应该编写/重载哪些函数?

【问题讨论】:

    标签: c++ inheritance comparison operator-overloading


    【解决方案1】:
    class Base // Base is an abstract class
    {
        virtual bool equals(const Base& b) = 0;
    };
    
    class A : public Base
    {
        virtual bool equals(const Base& base)
        {
            if (const A* a = dynamic_cast<const A*>(&base))
            {
                // Return true iff this and a are equal.
            }
            return false;
        }
    };
    
    class B : public Base
    {
        virtual bool equals(const Base& base)
        {
            if (const B* b = dynamic_cast<const B*>(&base))
            {
                // Return true iff this and b are equal.
            }
            return false;
        }
    };
    

    【讨论】:

    • 我不敢相信我没有想到这个...谢谢。我生病时再也不会编码了。
    【解决方案2】:

    在基类重载运算符:子类引用将被强制转换为基类引用。

    看不出设计有任何问题 - 没有更多上下文。

    【讨论】:

    • 问题在于Base没有信息或逻辑。如果我在Base::operator==() 中使用dynamic_cast&lt;&gt;,我必须考虑所有可能性,这是不可能的。
    • 所以 Base 不是一个“抽象”类,而是一个“接口”。如果它是一个接口——也就是说,你只有纯虚方法——那么 operator== 根本没有任何意义。如果 Base 对象没有任何状态,你会比较什么?
    【解决方案3】:

    我现在无法制作反例,但据我记得,比较运算符(作为传递、自反和对称的东西)将总是中断(并成为恶意错误的来源)与继承结合时。可能它不会破坏你的应用程序,你的用例,仅仅半年后当你子类化你的子类时......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-30
      • 1970-01-01
      相关资源
      最近更新 更多