在c ++上使用接口(抽象类)我需要强制任何类而不是继承接口来实现operator ==。 考虑这种情况:
class IBase
{
virtual void someFunc() const = 0;
}
class CInheritClass : public IBase
{
virtual void someFunc() const;
virtual bool operator== ( const CInheritClass& obj ) const;
}
void main()
{
CInheritClass instance;
}
类CInheritClass必须实现someFunc,因为它继承了Ibase,实现virtual bool operator== ( const CInheritClass& obj ) const;
不是必需的。
我希望以任何继承者X必须实现的方式修改IBase类
virtual bool operator== ( const X& obj ) const
以下代码将起作用:
template<class X>
class IBase
{
virtual void someFunc() const = 0;
virtual bool operator== ( const X& obj ) const = 0;
}
class CInheritClass : public IBase<CInheritClass>
{
virtual void someFunc() const;
virtual bool operator== ( const CInheritClass& obj ) const;
}
但我追求的是一个不使用模板的解决方案导致每个希望实现IBase的类必须继承IBase并将其自身作为模板类class X : public IBase<X>
,这对任何未来的开发人员来说都是一个令人困惑和不清楚的问题。看看我的代码。
任何想法?
答案 0 :(得分:5)
使用纯虚函数声明
virtual bool operator== ( const IBase& obj ) const = 0;
实施的一个例子:
bool CInheritClass ::operator==( const IBase& obj ) const
{
const CInheritClass *o = dynamic_cast<const CInheritClass*>(&obj);
if (o == NULL) return false;
// TODO
}
输入类型应该是基类,否则你将无法对基础对象进行多态调用比较
对于从模板继承的想法:警告,基类在2个派生类之间不再相同。 =&GT;基类的目的发生了变化:使用模板只需共享代码,强制用户实现函数并防止2派生类之间出现重复代码
这真的取决于你想做什么。它可以是一个好的设计,或者不是......
答案 1 :(得分:3)
仅供参考,模板版本通常被称为“Barton-Nackman技巧:” http://en.wikipedia.org/wiki/Barton%E2%80%93Nackman_trick
如果您希望派生类只能与其自身类型的其他对象(而不是抽象基类型)相比较,那么这就是使用的“技巧”,IMO。
编辑:这类似于Java实现Comparable接口的方式,因此并不是好(好)程序员不知道发生了什么: http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html答案 2 :(得分:1)
让我们分解你在这里要求的东西。您希望强制每个孩子使用自己类型的右侧实现operator==
。但是你也要求说运营商是虚拟的。由于每个子运算符的参数类型将与父虚拟方法的参数类型不同,因此所有您最终都将HIDING基类运算符。因此,您永远无法以多态方式调用它,并且比较的虚拟性根本不会有用。
相反,我建议只是删除父运算符的虚拟性,并且只需使用处理子类所需的==
。然后编译器会告诉你它什么时候丢失。
但是,如果你真的需要能够在基础对象上进行多态调用比较,那么你很可能必须使用像double dispatch这样的东西,以确保双方访问最派生类型并验证派生类型最多的类型是相同的(否则比较毫无意义)。
编辑:如果你真的需要这个功能,我没有看到模板基类有什么特别的错误 - 只需检查你的设计并确保你确实需要它。