优雅的对象比较

min*_*dog 9 c++ virtual function

当比较两个对象(相同类型)时,有一个比较函数,它采用同一个类的另一个实例是有意义的.如果我将它实现为基类中的虚函数,那么函数的签名也必须引用派生类中的基类.解决这个问题的优雅方法是什么?比较不应该是虚拟的吗?

class A
{
    A();
    ~A();
    virtual int Compare(A Other);
}

class B: A
{
    B();
    ~B();
    int Compare(A Other);
}

class C: A
{
    C();
    ~C();
    int Compare(A Other);
}
Run Code Online (Sandbox Code Playgroud)

Kyl*_*mek 1

它取决于 A、B 和 C 的预期语义以及 Compare() 的语义。比较是一个抽象概念,不一定具有单一的正确含义(或就此而言根本没有任何含义)。这个问题没有单一的正确答案。

这是两个场景,其中比较意味着具有相同类层次结构的两个完全不同的事物:

class Object 
{
    virtual int compare(const Object& ) = 0;
    float volume;
};

class Animal : Object 
{
    virtual int compare(const Object& );
    float age;
};

class Zebra  : Animal 
{
    int compare(const Object& );
};
Run Code Online (Sandbox Code Playgroud)

我们可以(至少)考虑两种方法来比较两只斑马:哪只更老,哪只体积更大?两种比较都是有效的并且易于计算;不同之处在于,我们可以使用体积来将斑马与任何其他物体进行比较,但我们只能使用年龄来将斑马与其他动物进行比较。如果我们希望compare()实现年龄比较语义,那么在Object类中定义compare()没有任何意义,因为语义不是在层次结构的这个级别定义的。值得注意的是,这些场景都不需要任何转换,因为语义是在基类级别定义的(无论是比较体积时的 Object,还是比较年龄时的 Animal)。

这提出了更重要的问题——某些类不适合单一的包罗万象的compare()函数。通常,实现多个明确说明要比较的内容的函数更有意义,例如compare_age()和compare_volume()。这些函数的定义可以发生在继承层次结构中语义变得相关的点,并且将它们适应子类应该是微不足道的(如果需要适应的话)。使用compare() 或operator==() 的简单比较通常只对简单的类有意义,其中正确的语义实现是明显且明确的。

长话短说......“这取决于”。