【问题标题】:Polymorphic operator<< from virtual base class来自虚拟基类的多态运算符<<
【发布时间】:2015-08-16 23:30:55
【问题描述】:

我想重载 Operator

Base* a = new A;
(*a) << 10;

我想使用这种语法,因为我的程序的另一部分使用

问题是,Base 是纯虚拟的,如果没有完整、有效的 Base 类,我不知道如何实现这种系统。例如:

class Base
{
public:
    virtual void aVirtualFunction() = 0;
    virtual Base operator<<( int ) = 0;
};

class A : public Base
{
    Base operator<<( int )
    {
        // Do something
    }
};

class B : public Base
{
    Base operator<<( int )
    {
        // Do something
    }
};

这会产生错误,因为 Base 是抽象的。

我不能只将重载放在继承的类中,因为我需要从指向基类的指针访问运算符而不强制转换为子类。

我的问题与Overloading << operator with polymorphism 中提出的问题非常相似,只是我的基类本身不是有效对象。

【问题讨论】:

  • 如果你在做多态,它必须是指针或引用。不能按价值计算。
  • 因为它是一个抽象类,所以不能按值返回。
  • @Pradheep 是的,我知道。我把它作为我尝试过的一个例子,以及似乎是实现它的唯一合理方法(即使它不起作用)。我想要的是一些设置运算符的方法,以便第一个示例可以工作。

标签: c++ inheritance polymorphism operator-overloading


【解决方案1】:

您的代码不起作用,因为您无法返回 Base 对象,因为它是纯虚拟的。而是返回对 Base 的引用。

然后,使用标准继承可以轻松处理整个事情。考虑以下代码:

class Base
{
public:
    virtual void aVirtualFunction() = 0;
    virtual Base& operator<<( int ) = 0;
};

class A : public Base
{
    virtual A& operator<<( int ) override
    {
        // Do something
        return *this;
    }
};

class B : public Base
{
    virtual B& operator<<( int ) override
    {
        // Do something
        return *this;
    }
};

DEMO

注意operator&lt;&lt;(int) 的重载不返回Base&amp;,而是返回A&amp;B&amp;。这称为协方差

【讨论】:

    【解决方案2】:

    您可以将Base::operator&lt;&lt; 的工作委托给一个纯虚函数,您可以在所有派生类中覆盖该函数,例如

    #include <iostream>
    #include <memory>
    
    class Base
    {
        virtual void delegate(int x) = 0;
    public:
        Base& operator<<( int x) // we define this only in Base
        {
            delegate(x); // delegate, this must be overridden in all derived classes
            return *this;
        }
        virtual ~Base() = default;
    };
    
    void Base::delegate(int x) // we can even define this
    {
        std::cout << "Base::delegate x = " << x << std::endl;
    }
    
    class A : public Base
    {
        void delegate(int x) override
        {
            std::cout << "A::delegate x = " << x << std::endl;
        }
    };
    
    class B : public Base
    {
        void delegate(int x) override
        {
            std::cout << "B::delegate x = " << x << std::endl;
        }
    };
    
    int main()
    {
        std::unique_ptr<Base> pBase(new B);
        *pBase << 42;
    }
    

    Live on Coliru

    【讨论】:

      【解决方案3】:

      如果你想使用多态,你不应该按值返回。您应该通过引用返回。

      请注意,您的 operator&lt;&lt; 未在您的基类中声明为虚拟。

      #include <iostream>
      
      class Base
      {
      public:
          virtual void aVirtualFunction() = 0;
          virtual Base& operator<<( int ) = 0;
      };
      
      class A : public Base
      {
          public:
          A& operator<<( int a)
          {
              // Do something
              a_ = a;
              return *this;
          }
      
          void aVirtualFunction()
          {
              std::cout << a_ << '\n';
          }
      
          int a_;
      };
      
      class B : public Base
      {
          public:
          B& operator<<( int a)
          {
              // Do something
              b_ = a;
              return *this;
          }
      
          void aVirtualFunction()
          {
              std::cout << b_ << '\n';
          }
      
          int b_;
      };
      
      int main(int, char**)
      {
          Base* a = new A;
          Base* b = new B;
          *a << 10;
          *b << 11;
      
          a->aVirtualFunction();
          b->aVirtualFunction();
      
          delete a;
          delete b;
      }
      

      【讨论】:

        猜你喜欢
        • 2018-06-21
        • 2018-12-01
        • 1970-01-01
        • 2020-02-15
        • 1970-01-01
        • 1970-01-01
        • 2011-09-08
        • 2011-10-10
        • 1970-01-01
        相关资源
        最近更新 更多