【问题标题】:overriding pure virtual operators覆盖纯虚拟运算符
【发布时间】:2012-12-02 10:34:53
【问题描述】:

我正在尝试创建一个计数器接口,强制所有派生类实现此接口:

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)’

【问题讨论】:

    标签: c++ operators overwrite pure-virtual


    【解决方案1】:

    你运气不好。您希望返回一个具有调用该函数的对象的 动态类型 的值。您不能: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== 是一个完全独立的问题,我将留给网站上的其他问题。

    顺便说一句,CounterInterface 需要一个虚拟析构函数。

    【讨论】:

      【解决方案2】:

      首先你应该替换

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

      通过

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

      其次,和“Olaf Dietsche”一样,它比我快 :-)

      【讨论】:

        【解决方案3】:

        你不能用纯虚成员函数来实例化一个类。由于您无法创建它们,因此您也不能像在

        中那样按值返回它们
        virtual CounterInterface  operator ++ (int) = 0;
        virtual CounterInterface  operator -- (int) = 0;
        

        【讨论】:

          猜你喜欢
          • 2016-12-16
          • 1970-01-01
          • 2019-10-21
          • 2011-03-31
          • 2021-11-01
          • 1970-01-01
          • 2016-02-05
          • 2021-09-30
          • 2013-10-04
          相关资源
          最近更新 更多