C++11 多态性:从基 class 指针调用派生的 class 方法
C++11 Polymorphism : Call derived class method from base class pointer
综上所述,我认为我的问题的答案是否定的。但是,比我聪明的人,我会抱有希望和服从。
我想从指向基 class 的指针调用派生 class 的 class 方法。重载并希望调用的继承方法是纯虚拟的。我能够让它在某些情况下工作,但在一种特定情况下不能工作,在这种情况下,纯虚拟方法包含参数的省略号占位符。
我想要的精华贴在下面,任何修复and/or的建议都非常感谢,谢谢。
#include <iostream>
class A
{
public:
virtual void setup()=0;
virtual void callFunction(std::string str, ...)=0;
};
class B: public A
{
public:
virtual void setup() {};
virtual void callFunction(std::string str, ...) { std::cout<<"\nB::callFunction("<<str<<")\n"; }; //compiles: not desired: a->callFunction("Hello World", 987); executes as B::callFunction
//virtual void callFunction(std::string str, ...)=0; compile error: error: cannot declare variable 'c' to be of abstract type 'C'
};
class C: public B
{
public:
void setup() { std::cout<<"\nC::setup\n"; };
void callFunction(std::string str, int i) { std::cout<<"\nC::callFunction("<<str<<") = "<<i<<"\n"; };
};
int main()
{
C c;
A* a = (A*) new C;
c.setup();
c.callFunction("Hello World", 123);
a->setup(); //WHY: does this pure virtual function still execute C::setup, this is desired for pure virtual method callFunction derived from class A
a->callFunction("Hello World", 987);
return 0;
}
作为评论的结论:
您不能通过在派生的 class 中重载虚函数来影响虚分派。
过载解决和虚拟调度是正交的,前者发生在后者之前。
所以你可以做的是声明多个重载,它们是单独虚拟分派的。
在您的问题中,这只需要将 int
重载作为纯虚拟添加到 A
:
class A
{
public:
virtual void setup()=0;
virtual void callFunction(std::string, ...)=0;
virtual void callFunction(std::string, int)=0;
};
为确保虚函数实现与这些重载正确匹配,您应该将 override
说明符添加到派生的 classes 中的所有实现,例如:
void callFunction(std::string str, int i) override { std::cout<<"\nC::callFunction("<<str<<") = "<<i<<"\n"; };
如果您需要支持更多参数类型,只需将另一个纯虚拟重载添加到 A
并在继承层次结构中的某个位置实现它。
综上所述,我认为我的问题的答案是否定的。但是,比我聪明的人,我会抱有希望和服从。
我想从指向基 class 的指针调用派生 class 的 class 方法。重载并希望调用的继承方法是纯虚拟的。我能够让它在某些情况下工作,但在一种特定情况下不能工作,在这种情况下,纯虚拟方法包含参数的省略号占位符。
我想要的精华贴在下面,任何修复and/or的建议都非常感谢,谢谢。
#include <iostream>
class A
{
public:
virtual void setup()=0;
virtual void callFunction(std::string str, ...)=0;
};
class B: public A
{
public:
virtual void setup() {};
virtual void callFunction(std::string str, ...) { std::cout<<"\nB::callFunction("<<str<<")\n"; }; //compiles: not desired: a->callFunction("Hello World", 987); executes as B::callFunction
//virtual void callFunction(std::string str, ...)=0; compile error: error: cannot declare variable 'c' to be of abstract type 'C'
};
class C: public B
{
public:
void setup() { std::cout<<"\nC::setup\n"; };
void callFunction(std::string str, int i) { std::cout<<"\nC::callFunction("<<str<<") = "<<i<<"\n"; };
};
int main()
{
C c;
A* a = (A*) new C;
c.setup();
c.callFunction("Hello World", 123);
a->setup(); //WHY: does this pure virtual function still execute C::setup, this is desired for pure virtual method callFunction derived from class A
a->callFunction("Hello World", 987);
return 0;
}
作为评论的结论:
您不能通过在派生的 class 中重载虚函数来影响虚分派。
过载解决和虚拟调度是正交的,前者发生在后者之前。
所以你可以做的是声明多个重载,它们是单独虚拟分派的。
在您的问题中,这只需要将 int
重载作为纯虚拟添加到 A
:
class A
{
public:
virtual void setup()=0;
virtual void callFunction(std::string, ...)=0;
virtual void callFunction(std::string, int)=0;
};
为确保虚函数实现与这些重载正确匹配,您应该将 override
说明符添加到派生的 classes 中的所有实现,例如:
void callFunction(std::string str, int i) override { std::cout<<"\nC::callFunction("<<str<<") = "<<i<<"\n"; };
如果您需要支持更多参数类型,只需将另一个纯虚拟重载添加到 A
并在继承层次结构中的某个位置实现它。