导出重载运算符,但仅在相同类型上运行 [英] Derive overloaded operator, but operate on same types only

查看:104
本文介绍了导出重载运算符,但仅在相同类型上运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个基类和两个派生自它的类:

Suppose I have a base class and two classes derived from it:

class Base
{
protected:
    double value;
public:
    virtual ~Base();

    Base(double value) : value(value) {}
    Base(const Base& B) { value=B.value; }

    Base operator+ (const Base& B) const { 
        return Base(value+B.value); 
    }

};

class final Derived1 : public Base {
public:
    Derived1(double value) : Base(value) {}
};

class final Derived2 : public Base {
public:
    Derived2(double value) : Base(value) {}
};

我要完成以下操作:

int main(int argc, char *argv[])
{
    Derived1 a = Derived1(4.0);
    Derived2 b = Derived2(3.0);

    a+a; // this should return a Derived1 object
    b+b; // this should return a Derived2 object

    a+b; // this should FAIL AT COMPILE TIME

    return 0;
}

换句话说,我想保证继承的 operator + 仅对与调用实例相同类型的对象进行操作。

In other words, I want to guarantee that the inherited operator+ only operates on objects of the same type as the calling instance.

如何清洁?我发现自己重新定义每个类的运算符:

How do I do this cleanly? I found myself re-defining the operator for each class:

class final Derived1 : public Base {
    ...
    Derived1 operator+ (const Derived1& D1) const {
        return Derived1(value+D1.value);
    }
    ...
};

class final Derived2 : public Base {
    ...            
    Derived2 operator+ (const Derived2& D1) const {
        return Derived2(value+D1.value);
    }
    ...
};

但这只是一个痛苦。此外,它似乎不是正确的代码重用于我。

But that's just a pain. Moreover, it doesn't seem like proper code re-use to me.

这里使用的正确技术是什么?

What is the proper technique to use here?

推荐答案

如果您可以确保 Derived1 Derived2 是叶类(即没有其他类可以从它们派生),你可以使用好奇地重现模板模式

If you can make sure Derived1 and Derived2 are leaf classes (i.e. no other class can derive from them) you can do this with the curiously recurring template pattern:

template <typename T>
class BaseWithAddition : public Base {
    T operator+(T const& rhs) const {
        return T(value + rhs.value);
    }
};

class final Derived1 : public BaseWithAddition<Derived1> {
    // blah blah
};

class final Derived2 : public BaseWithAddition<Derived2> {
    // blah blah
};

final 是一个C ++ 11 )

(final is a C++11 feature that prevents further derivation.)

如果允许派生 Derived1 Derived2 那么你会遇到麻烦:

If you allow derivation from Derived1 and Derived2 then you get trouble:

class Derived3 : public Derived1 {};
Derived3 d3;
Derived1 d1;
Derived1& d3_disguised = d3;
d1 + d3_disguised; // oooops, this is allowed

在编译时没有办法防止这种情况。即使您希望允许它,也不容易在没有多个分派的情况下为此操作获取正确的语义>。

There's no way to prevent this at compile-time. And even if you want to allow it, it's not easy to get decent semantics for this operation without multiple dispatch.

这篇关于导出重载运算符,但仅在相同类型上运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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