假设我有一个基类和两个从它派生的类:
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+
只对对象进行操作同类型的作为调用实例。
我该如何干净地做到这一点?我发现自己为每个类重新定义了运算符:
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);
}
...
};
但这只是一种痛苦。此外,对我来说,这似乎不是正确的代码重用。
这里使用的正确技术是什么?
如果你能确定Derived1
and Derived2
是叶类(即没有其他类可以从它们派生),您可以使用奇怪的重复模板模式 http://en.wikipedia.org/wiki/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 功能,可防止进一步推导。)
如果您允许派生自Derived1
and Derived2
然后你就会遇到麻烦:
class Derived3 : public Derived1 {};
Derived3 d3;
Derived1 d1;
Derived1& d3_disguised = d3;
d1 + d3_disguised; // oooops, this is allowed
没有办法在编译时阻止这种情况。即使您想允许它,如果没有适当的语义,也不容易获得此操作的正确语义。多次调度 http://en.wikipedia.org/wiki/Multimethods.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)