C ++ provides conditions for inherited classes

I would like to define an abstract base class X and do the following:

a) each concrete class Y inheriting from X defines a constructor Y (int x)

b) it should be possible to check if two objects of Y are equal.

For a, one not-so-good solution is to put a pure virtual fromInt method in X which the concrete class will have to define. But I can’t enforce.

For b) I cannot use pure virtual method in X

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

since in overridden classes this remains undefined. Not enough to determine

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

because the types do not match. How to solve these problems?

+3
source share
6 answers

, . , .

==,

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

. equals (const BaseClass & other), .

: . , , . , .

+3

b) virtual bool operator == (const X & other) const = 0 X.

const Y & other , Ys Xs, dynamic_cast, , , .

+2

.

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

class X {
 ...
+2

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;
  }
};

, , , .

0

a) , , -

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

b) google "multi methods" ++

0

Forcing to build from the whole makes no sense: each derived class is free to define its own constructors as it sees fit. However, you can force them to pass an integer to the base class ... but that makes no sense.

operator== also distorted, however you can get its gist:

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);
}

You can try to embellish it a bit using templates and CRTP, but what if Derivedit was inherited? it will not be executed.

0
source

Source: https://habr.com/ru/post/1741000/


All Articles