Abstract operator +?

I have a class:

class base
{
public :
 base & operator +=(const int value) = 0;
 // base operator + (const int val) = 0; // HOW DO I DO THIS ?
};

And the child class that derives from it

class derived : public base
{
public :
 derived() : m_val(0) {}
 derived(const derived & val) : m_val(val.m_val) {}
 base & operator = (const derived& value) // POSSIBLE TO RETURN A REFERENCE TO BASE
 { m_val = value.m_val; return *this; }
 base & operator +=(const int val)
 { m_val += val; return *this; }
 /* operator + overload here */
 // base operator + (...) // IMPOSSIBLE TO RETURN A VALUE
protected :
int m_val;
};

I really need to have a + operator defined in the base class, which on average should remain abstract. It’s hard for me to achieve, since a typical + operator returns a value, while an abstract class cannot be instantiated - so I ended up in catch situation # 22. Is there an acceptable solution for this?

Hello

+3
source share
5 answers

The + () operator should almost always be implemented as a free function, so there is no need to declare it virtual (which you do not, but should avoid a syntax error) in the database.

, - - operator +(), operator +() , - +().

+10

. ( , "" OP)

std::advance, <iterator>.

int DoStuff(iterator &it)
{
    iterator a = it;
    std::advance(a, 2);

    // (...)
    return 0;
}

, : P

+1

, , . , , undefined. , , , . , , .

, , , , .

0

, OP .

, std::vectors T [], T = byte = unsigned char.

, , . :

** , , , **

class iterator
{
  public :
    virtual iterator & operator -- ()    = 0;
    virtual iterator & operator -- (int) = 0;
    virtual iterator & operator ++ ()    = 0;
    virtual iterator & operator ++ (int) = 0;
    virtual iterator & operator += (int n) = 0;
    virtual iterator & operator -= (int n) = 0;
    virtual bool operator == (const iterator & o) = 0;
    virtual bool operator != (const iterator & o) = 0;
};

, :

/*! \brief ptr iterator can be used to iterate over classic c-style arrays */
class ptr_iterator : public iterator
{
  public :
    ptr_iterator() : m_p(NULL) {}
    ptr_iterator(byte * b) : m_p(b) {}

    iterator & operator = (const ptr_iterator &o)
    { m_p = o.m_p; return *this; }
    iterator & operator = (byte * b)
    { m_p = b; return *this; }
    virtual iterator & operator -- ()
    { --m_p; return *this; }
    virtual iterator & operator -- (int)
    { m_p--; return *this; }
    virtual iterator & operator ++ ()
    { ++m_p; return *this; }
    virtual iterator & operator ++ ()
    { m_p++; return *this; }
    virtual iterator & operator += (int n)
    { m_p += n; return *this; }
    virtual iterator & operator -= (int n)
    { m_p -= n; return *this; }
    virtual bool operator == (const iterator & o)
    { return ((ptr_iterator*)&o)->m_p == m_p; }
    virtual bool operator != (const iterator & o)
    { return ((ptr_iterator*)&o)->m_p != m_p; }

  private :
    byte * m_p;
};

, , std::vector

class std_iterator: { typedef typename C:: iterator c_iterator; :    = (const c_iterator i)   {m_it = i; return * this; }    = (const std_iterator o)   {m_it = o.m_it; return * this; }

virtual iterator & operator ++ ()
{ ++m_it; return *this; }
virtual iterator & operator ++ (int)
{ m_it++; return *this; }
virtual iterator & operator -- ()
{ --m_it; return *this; }
virtual iterator & operator -- (int)
{ m_it--; return *this; }
virtual iterator & operator += (int n)
{ m_it += n; return *this; }
virtual iterator & operator -= (int n)
{ m_it -= n; return *this; }

virtual bool operator == (const iterator &o)
{ return ((std_iterator*)&o)->m_it == m_it; }
virtual bool operator != (const iterator &o)
{ return ((std_iterator*)&o)->m_it != m_it; }
bool operator == (const c_iterator &i)
{ return m_it == i; }
bool operator != (const c_iterator &i)
{ return m_it != i; }

:

c_iterator m_it;

};

, .

, :

int DoStuff(iterator &it); 

- . , , - :)

, :

std_iterator > it = my_vector.begin();// std_iterator > other = it;//

int DoStuff(iterator &it)
{
  iterator a = it + 2;   // THIS IS ILLEGAL DUE TO ABSTRACT-NESS OF THE BASE CLASS
                         // YET I STILL NEED THIS TO WORK. HOW DO I ACHIEVE THAT ?
                         // DO I SACRIFICE THE ABSTRACT-NESS OF THE BASE CLASS ?
                         // AT THIS POINT I WAS SERIOUSLY CONSIDERING AN OVERLOAD OF THE
                         // + OPERATOR BUT HAVE NO IDEA HOW TO DO IT WITH AN ABSTRACT 
                         // CLASS 
  // (...)
  return 0;
}
0

:

  • .
  • .

: "pimpl" "letter-envelope". : , :

class impl {
public:
  virtual impl *do_add(const impl *other) const = 0;
};

class handle {
  impl *_impl;
  handle(impl *i): _impl(i) {}
public:
  handle(): _impl(NULL) {}

  handle operator+(const handle &other) const {
    impl *new_impl = _impl->do_add(other._impl);
    return handle(new_impl);
  }
};

impl . - , "" , . , impl.

impl .

: . . , , . - , , , , , "" , .. . , impl ( _impl = other._impl- > clone(), clone() - , impl) . , , const-correct .

0
source

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


All Articles