7

在 c++ 上使用接口(抽象类)我需要强制任何类而不是继承接口来实现运算符 ==。考虑这种情况:

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>,这对于任何可能查看我的代码的未来开发人员来说都是令人困惑和不清楚的。任何的想法 ?

4

3 回答 3

7

使用纯虚函数声明

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 个派生类之间不再相同。=>基类的目的改变了:使用模板你只是共享代码,强制用户实现功能并防止2个派生类之间的重复代码

这真的取决于你想要做什么。它可以是一个好的设计,也可以不是......

于 2013-01-01T15:39:50.020 回答
4

仅供参考,模板版本通常称为“Barton-Nackman 技巧”: http ://en.wikipedia.org/wiki/Barton%E2%80%93Nackman_trick

如果您希望您的派生类只能与它们自己类型的其他对象(而不是抽象基类型)相比较,那么这就是使用的“技巧”,IMO。

EDIT: This is similar to the way that Java implements the Comparable interface, so it's not as if (good) programmers won't know what's going on: http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html

于 2014-03-21T19:48:19.767 回答
1

让我们在这里分解您的要求。您想强制每个孩子operator==使用其自己类型的右侧来实现。但是您还要求将所述操作员设为虚拟。由于每个子运算符的参数类型将与父虚拟方法的参数类型不同,因此您最终会隐藏基类运算符。因此,您将永远无法多态地调用它,并且比较的虚拟性根本没有用处。

相反,我建议只是删除父运算符的虚拟性,并在使用==子类时使用您需要的位置。然后编译器会告诉你它什么时候丢失。

但是,如果您确实需要能够对基础对象进行多态调用比较,则很可能必须使用双重调度之类的东西来确保双方都访问派生最多的类型并验证派生最多的类型是否相同(否则比较是没有意义的)。

编辑:如果您真的需要该功能,我看不出模板基类有什么特别错误 - 只需检查您的设计并确保您确实需要它。

于 2013-01-01T15:46:38.797 回答