导出重载运算符,但仅在相同类型上运行 [英] Derive overloaded operator, but operate on same types only
问题描述
假设我有一个基类和两个派生自它的类:
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屋!