5

すべての派生クラスにこのインターフェイスを実装させるカウンター インターフェイスを作成しようとしています。

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

ただし、このクラス定義を含めるだけでは、以下のエラーが発生します。

残念ながら、post 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)’
4

3 に答える 3

5

あなたは運が悪いです。関数が呼び出されたオブジェクトの動的な型で値を返したい。できないこと: C++ の (非ポインター) 値は、共変の戻り値の型にすることはできません。これは、C++ の値による戻り値が静的型とは異なる動的型を持つことができないためです。

これは、基本的に virtual の実装と同じ問題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==はまったく別の問題であり、サイトの他の質問に任せます.

ところで、CounterInterface仮想デストラクタが必要です。

于 2012-12-14T12:17:20.510 に答える
2

純粋仮想メンバー関数を使用してクラスをインスタンス化することはできません。それらを作成できないため、値で返すこともできません。

virtual CounterInterface  operator ++ (int) = 0;
virtual CounterInterface  operator -- (int) = 0;
于 2012-12-14T12:16:17.913 に答える
1

まず、交換します

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

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

第二に、「Olaf Dietsche」と言ったのと同じことですが、私よりも速かったです :-)

于 2012-12-14T12:17:07.377 に答える