繁体   English   中英

如何纠正多态性

[英]How to Correct the Polymorphism

我有以下代码。

#include <iostream>

class Base1
{
public:

  void print(){std::cout<<"Printing Base1\n";}
};


class Derived1: public Base1
{
public:
  void print_1(){std::cout<<"Printing Derived1 \n";}
};



class Base2
{
public:
  void myFunction1( Base1& b1)
  {
    myFunction2(b1);

  }

  virtual void myFunction2( Base1& b1)
  {
    b1.print();
  }
};

class Derived2: public Base2
{
public:
  void myFunction2( Derived1& d1)
  {
    d1.print_1();
  }
};





int main()
{
  Base1 b1;
  Derived1 d1;
  Base2 b2;
  Derived2 d2;
  b2.myFunction1(b1);
  d2.myFunction1(d1);
  return 0;
}

结果如下:

Printing Base1
Printing Base1

我想到了以下输出

Printing Base1
Printing Derived1

获得所需输出的一种方法是执行以下操作。

class Derived2: public Base2
    {
    public:
      void myFunction2( Base1& b1)
      {
        Derived1* d1 = static_cast<Derived1*> (&b1);
        d1.print_1();
      }
    };

我想允许Derived2仅处理Derived1,而不处理Base1。 否则,某些用户可能会使用Base1对象调用Derived2 :: myFunction2,这可能会使程序崩溃。

有没有好的解决方案?

myFunction2()Derived2不覆盖myFunction2()Base2

虚拟函数仅在其签名完全匹配时才被覆盖。 此派生类中的函数采用与基类中不同的参数。 因此,它不会覆盖。

第一步,必须使其覆盖。

class Derived2: public Base2
{
public:
  void myFunction2( Base1& d1) override;
};

现在已被覆盖。 如果像我在这里那样明确指定了override限定符,则编译器已经对您大喊大叫。

现在,您的目标是拥有myFunction2所做的一切,仅使其对Derived1类生效,对于所有其他Base1类,使用超类所做的事情。

好。 这将需要更多的工作,并且后续操作会有些困难。 需要发生的是这次在Base1另一个虚拟继承:

class Derived2: public Base2
{
public:
  void myFunction2( Base1& d1) override
  {
      d1.print_from_Derived2( *this );
  }
};

现在,您需要定义Base1::printDerived2() ,它将调用print() ,这是在这种情况下根据您的问题而发生的情况:

class Base1
{
public:
       virtual void print_from_Derived2( Derived2 &)
       {
              print();
       }
};

现在,在Derived1中覆盖它,以便将拼图的最后一部分放在一起:

class Derived1 : public Base1
{
public:
       void print_from_Derived2( Derived2 &) override
       {
              // Do whatever print() from Derived2 needs to do, for
              // this object, which is Derived1.
       }
};

在这里,您将完成Derived2只打印Derived1 这是一条circuit回曲折的路线,但是您最终到达了两个参与者都是Derived1Derived2 ,没有违反任何规则,也没有任何丑陋的演员。

您将需要在此处做一堆前向声明,以便将所有这些可移动的部分缝合在一起。 我的示例只是简单的简化,它们显然相互引用,并且必须分解为单独的声明和定义以及适当的前向声明。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM