C++我可以创建一个接口,通过在接口中实现的运算符重写来调用在子类中具体实现的方法吗?

jhdbpxl9  于 2022-11-19  发布在  其他
关注(0)|答案(1)|浏览(131)

如果这个问题很愚蠢,请提前道歉,但是:
我接口道:

template <class T>
class IEqualCompare {
public:
    virtual bool IsEqual(const T b) = 0;
    bool operator== (const T b) { return this->IsEqual(b); }     //Both are implemented in cpp file
    bool operator!= (const T b) { return !(this->IsEqual(b)); }
};

还有一个类:

class Dimentions : IEqualCompare<Dimentions> {

...

bool IsEqual(const Dimentions b) { //IsEqual logic for this specific class }

...

}

我只想为IEqualCompare的每个子类实现IsEqual方法,因为运算符重载(==,!=)中的逻辑对于任何IEqualCompare派生类都是相同的。
到目前为止,我总是简单地将两个运算符覆盖定义为虚拟的,并在每个类中实现它们,但由于逻辑应该总是相同的,我想知道这是否可能,或者这是糟心的编程。
提前感谢您的解答。

mwyxok5s

mwyxok5s1#

首先,由于比较运算符通常不用于修改被比较的对象,因此它们(和IsEqual方法)应声明为const,作为const correctness的一般做法。除其他外,它有助于程序员避免在语义非修改操作期间意外修改对象的错误,并通过利用更多关于代码行为的假设,帮助优化程序生成更高效的二进制文件。此外,为了避免不必要的复制,运算符的参数通常应该 by reference,在我们的例子中是 const reference,这样被引用的对象就不能被修改。
现在,如果您只想根据派生类的IsEqual方法自动将相等比较运算符添加到派生类中,而不想使用动态多态/调度(这对于CRTP基类是毫无意义的),因此根本不需要将IsEqual设为虚拟的,甚至根本不需要将IsEqual设为基类的成员。因此您可以静态地将this指针转换为T*,并通过生成的指针调用T的非虚拟IsEqual方法,从而避免使用成本更高的virtual dispatch机制。示例:

template<typename T>
class AddEqualComparisons {
public:
    bool operator==(const T& b) const { return static_cast<T*>(this)->IsEqual(b); }
    bool operator!=(const T& b) const { return !static_cast<T*>(this)->IsEqual(b); }
};

class Dimensions : public AddEqualComparisons<Dimensions> {
    bool IsEqual(const Dimensions& rhs) const {
        // ...
    }
};

相关问题