C ++对继承的类强制执行条件

时间:2010-04-13 21:28:55

标签: c++ inheritance operators constraints equality

我想定义一个抽象基类X并强制执行以下操作:

a)从X继承的每个具体类Y定义了一个构造函数Y(int x)

b)应该可以测试两个Y对象是否相等。

对于a,一个不太好的解决方案是在X中放置一个纯虚拟的fromInt方法 哪个具体类必须定义。但我不能强制执行。

对于b),我似乎无法在X

中使用纯虚方法

bool operator == (const X& other) const =0;

因为在重写的类中,这仍然是未定义的。仅定义

是不够的

bool operator == (const Y& other) const { //stuff}

因为类型不匹配。我该如何解决这些问题?

6 个答案:

答案 0 :(得分:3)

您可以通过将无参数构造函数设为私有并在基类中具有公共单个int参数构造函数来强制构造。只要基类有一些纯虚方法,那么你的子类必须调用该构造函数。

至于运算符==,尝试定义

bool operator == (const BaseClass& other) const { .. };

在所有子类中。最糟糕的情况是,您可以在基础中定义一个纯粹虚拟的公共等于(const BaseClass& other)方法。

编辑:强制构造函数并不完全正确。我建议强制子类调用单个参数构造函数。它们可以有一个无参数构造函数,它将常量传递给构造函数中的基数。

答案 1 :(得分:2)

对于b),您可以在X中定义virtual bool operator == (const X & other) const = 0

你不能在比较中使用const Y & other作为参数,但是Ys会自动转换为Xs然后你可以使用dynamic_cast查看它是否是一个你可以比较的类。

答案 2 :(得分:2)

有一个简单的解决方案。

// Class X
// (... some documentation ...)
//
// ** NOTE: All subclasses of X must have a constructor that takes a single int,
// ** and overload operator==.

class X {
 ...

答案 3 :(得分:0)

a - 如果您使用CRTP以及所有用户代码必须继承的中介,朋友,模板化子类,则应该可以使用。像这样:


struct X 
{
  virtual bool compare(X const&) const = 0;
private:
  X();

  template < typename T >
  friend struct client_base; // don't recall the correct code here.
};


template < typename Sub >
struct client_base : X
{
  // use boost::concepts to verify Sub has Sub(int)
  Sub() : X() {}
};

struct Y : client_base<Y>
{
  Y(int);

  bool compare(X const& x)
  {
    if ((Y* other = dynamic_cast<Y*>(x)) && *other == *this) return true;
    return false;
  }
};

显然,我已经离开了很多让你想出这个完整的解决方案。

答案 4 :(得分:0)

a)对我来说没有意义,但你可以创造一些东西

template< typename T >
Base* create( int x )
{
    return T::create( x );
}

for b)向谷歌询问c ++中的“多方法”实现

答案 5 :(得分:0)

强制从整数构造是没有任何意义的:每个派生类都可以自由地定义它的构造函数。但是,你可以强制它们将一个整数传递给基类......不管它是否更有意义。

operator==也是扭曲的,但你可以得到它的本质:

class Base
{
public:
  bool operator==(const Base& rhs) const;
  bool operator!=(const Base& rhs) const { return !(*this == rhs); }

private:
  virtual bool equals(const Base& rhs) const = 0; // will pass only objects
                                                  // of the same dynamic type
};

bool Base::operator==(const Base& rhs) const
{
  return typeid(*this) == typeid(rhs) && this->equals(rhs);
}

bool Derived::equals(const Base& rhs) const // We KNOW Base is actually a Derived
{
  return *this == static_cast<const Derived&>(rhs);
}

您可以尝试使用模板和CRTP对其进行一些美化,但如果继承了Derived该怎么办?它不会成立。