переопределение чисто виртуальных операторов

Я пытаюсь создать интерфейс счетчика, который заставляет все производные классы реализовать этот интерфейс:

class CounterInterface
{
public:
virtual CounterInterface& operator ++ () = 0;
virtual CounterInterface  operator ++ (int) = 0;
virtual CounterInterface& operator -- () = 0;
virtual CounterInterface  operator -- (int) = 0;
virtual bool operator == ( const CounterInterface o ) const   = 0;
virtual operator uint32_t () const = 0;
virtual void reset() = 0;
};

Однако, только включение этого определения класса приводит к ошибке ниже.

К сожалению, сообщение inc не может быть определено как ссылка.

Любые идеи, как решить эту проблему курица / яйцо?

CounterInterface.h:25:29: error: invalid abstract return type for member function ‘virtual libceis::CounterInterface libceis::CounterInterface::operator++()’
CounterInterface.h:22:8: note:   because the following virtual functions are pure within ‘libceis::CounterInterface’:
CounterInterface.h:25:29: note:   virtual libceis::CounterInterface libceis::CounterInterface::operator++()
CounterInterface.h:26:29: note:   virtual libceis::CounterInterface libceis::CounterInterface::operator++(int)
CounterInterface.h:27:29: note:   virtual libceis::CounterInterface libceis::CounterInterface::operator--()
CounterInterface.h:28:29: note:   virtual libceis::CounterInterface libceis::CounterInterface::operator--(int)
CounterInterface.h:29:17: note:   virtual bool libceis::CounterInterface::operator==(libceis::CounterInterface) const
CounterInterface.h:30:12: note:   virtual libceis::CounterInterface::operator uint32_t() const
CounterInterface.h:31:17: note:   virtual void libceis::CounterInterface::reset()
CounterInterface.h:26:29: error: invalid abstract return type for member function ‘virtual libceis::CounterInterface libceis::CounterInterface::operator++(int)’

5

Решение

Не повезло тебе. Вы хотите вернуть значение с динамический тип объекта вызывается функция. Вы не можете: (не указатель) значения в C ++ не могут быть ковариантными возвращаемыми типами, потому что возвращаемое значение в C ++ не может иметь динамический тип, отличный от его статического типа.

Это в основном та же проблема, что и реализация виртуальной clone(), Он не может вернуться по значению. Вы будете в беде, даже если CounterInterface не был абстрактным классом, но вместо того, чтобы замечать это, когда код не компилируется, вы заметите это, когда возвращаемый объект будет разрезан.

То, что вы могли бы сделать, это расширить дизайн. Напишите класс, который содержит (умный) указатель на экземпляр CounterInterface, Этот тип может быть возвращен по значению и, следовательно, может реализовывать интерфейс, который вы хотите. Это можно сделать, вызвав чисто виртуальную функцию CounterInterface *clone() (или же unique_ptr<CounterInterface> clone()), который выделяет и возвращает новый экземпляр конкретного класса, который реализует интерфейс. Для операторов, которые работают как виртуальные функции, вы можете оставить их включенными CounterInterface и ваш класс-оболочка может вызывать через него, или вы можете переименовать их в виртуальном интерфейсе:

class Counter {
unique_ptr<CounterInterface> ctr;
public:
Counter(unique_ptr<CounterInterface> c) : ctr(std::move(c)) {}
Counter(CounterInterface *c) : ctr(c) {}
Counter &operator++() {
ctr->increment(); // or ++(*ctr)
return *this;
}
Counter operator++(int) {
Counter ret(ctr->clone());
ctr->increment();
return ret;
}
operator uint32_t() const {
return *ctr;
}
void reset() {
return ctr->reset();
}
};

виртуальный operator== это отдельная проблема, которую я оставлю другим вопросам на сайте.

Btw, CounterInterface нужен виртуальный деструктор.

5

Другие решения

Вы не можете создать экземпляр класса с чисто виртуальными функциями-членами. Поскольку вы не можете создать их, вы также не можете вернуть их по значению, как вы это делаете в

virtual CounterInterface  operator ++ (int) = 0;
virtual CounterInterface  operator -- (int) = 0;
2

Прежде всего вы должны заменить

virtual bool operator == ( const CounterInterface o ) const   = 0;

от

virtual bool operator == ( const CounterInterface &o ) const   = 0;

Во-вторых, то же самое, что сказал «Олаф Дитче», было быстрее, чем я 🙂

1
По вопросам рекламы [email protected]