我有以下代码。
#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回曲折的路线,但是您最终到达了两个角色都是Derived1
和Derived2
的地方,没有违反任何规则,也没有任何丑陋的演员。您将需要在此处做一堆前向声明,以便将所有这些可移动的部分缝合在一起。我的示例只是简单的简化,它们显然相互引用,并且必须分解为单独的声明和定义以及适当的前向声明。
关于c++ - 如何纠正多态性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41383297/