Rod*_*uis 0 c++ oop code-reuse class operator-overloading
假设我有一个基类和两个派生自它的类:
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) {}
};
Run Code Online (Sandbox Code Playgroud)
我想完成以下任务:
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;
}
Run Code Online (Sandbox Code Playgroud)
换句话说,我想保证继承operator+只对与调用实例相同类型的对象进行操作.
我该如何干净利落地做到这一点?我发现自己为每个类重新定义了运算符:
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);
}
...
};
Run Code Online (Sandbox Code Playgroud)
但那只是一种痛苦.此外,它似乎不适合我重复使用代码.
在这里使用的正确技术是什么?
如果你可以确定Derived1并且Derived2是叶子类(即没有其他类可以从它们派生),你可以使用奇怪的重复模板模式来做到这一点:
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
};
Run Code Online (Sandbox Code Playgroud)
(final是一个阻止进一步派生的C++ 11特性.)
如果您允许派生Derived1,Derived2那么您会遇到麻烦:
class Derived3 : public Derived1 {};
Derived3 d3;
Derived1 d1;
Derived1& d3_disguised = d3;
d1 + d3_disguised; // oooops, this is allowed
Run Code Online (Sandbox Code Playgroud)
在编译时无法阻止这种情况.即使您想要允许它,如果没有多次调度,也不容易为此操作获得合适的语义.