对于类层次结构,什么是重载operator ==的正确方法? [英] What's the right way to overload operator== for a class hierarchy?

查看:131
本文介绍了对于类层次结构,什么是重载operator ==的正确方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下类层次结构:

Suppose I have the following class hierarchy:

class A
{
    int foo;
    virtual ~A() = 0;
};

A::~A() {}

class B : public A
{
    int bar;
};

class C : public A
{
    int baz;
};

重载运算符== 这些类?如果我让他们所有的免费功能,那么B和C不能利用A的版本而不投射。它也会防止有人做一个深层比较,只有引用A.如果我使他们虚拟成员函数,那么派生版本可能如下所示:

What's the right way to overload operator== for these classes? If I make them all free functions, then B and C can't leverage A's version without casting. It would also prevent someone from doing a deep comparison having only references to A. If I make them virtual member functions, then a derived version might look like this:

bool B::operator==(const A& rhs) const
{
    const B* ptr = dynamic_cast<const B*>(&rhs);        
    if (ptr != 0) {
        return (bar == ptr->bar) && (A::operator==(*this, rhs));
    }
    else {
        return false;
    }
}

同样,我还是要错误)。这是否有首选方法?

Again, I still have to cast (and it feels wrong). Is there a preferred way to do this?

更新:

只有两个答案到目前为止,但它看起来像正确的方式类似于赋值运算符:

There are only two answers so far, but it looks like the right way is analogous to the assignment operator:


  • li>
  • 在非叶类中受保护的非虚拟

  • 在叶类中公共非虚拟

任何用户尝试比较不同类型的两个对象将无法编译,因为基函数是受保护的,叶类可以利用父类的版本来比较该部分数据。 p>

Any user attempt to compare two objects of different types will not compile because the base function is protected, and the leaf classes can leverage the parent's version to compare that part of the data.

推荐答案

对于这种层次结构,我肯定会遵循Scott Meyer的Effective C ++建议,避免使用任何具体的基类。

For this sort of hierarchy I would definitely follow the Scott Meyer's Effective C++ advice and avoid having any concrete base classes. You appear to be doing this in any case.

我将实现 operator == 作为一个自由函数,可能

I would implement operator== as a free functions, probably friends, only for the concrete leaf-node class types.

如果基类必须有数据成员,那么我将提供一个(可能受保护的)非虚拟助手函数在基类( isEqual ,说)中,导出类' operator == 可以使用

If the base class has to have data members, then I would provide a (probably protected) non-virtual helper function in the base class (isEqual, say) which the derived classes' operator== could use.

Eg

bool operator==(const B& lhs, const B& rhs)
{
    lhs.isEqual( rhs ) && lhs.bar == rhs.bar;
}

通过避免使用运算符== 在抽象基类上工作,并保持比较函数受保护,你不会偶然在客户端代码中只有两个不同类型对象的基础部分被比较。

By avoiding having an operator== that works on abstract base classes and keeping compare functions protected, you don't ever get accidentally fallbacks in client code where only the base part of two differently typed objects are compared.

我不知道是否使用 dynamic_cast 实现虚拟比较函数,我不愿意这样做,但如果有证明需要因为它可能在基类中有一个纯虚函数( operator == ),然后在具体的派生类中被覆盖像这样,使用运算符== 作为派生类。

I'm not sure whether I'd implement a virtual compare function with a dynamic_cast, I would be reluctant to do this but if there was a proven need for it I would probably go with a pure virtual function in the base class (not operator==) which was then overriden in the concrete derived classes as something like this, using the operator== for the derived class.

bool B::pubIsEqual( const A& rhs ) const
{
    const B* b = dynamic_cast< const B* >( &rhs );
    return b != NULL && *this == *b;
}

这篇关于对于类层次结构,什么是重载operator ==的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆