我有一个班级:
class ProjectService : public CProjectT<CSoapMSXMLInetClient>
{
...
}
我在此派生类中实现了HRESULT ConnectToServer();
函数。然后我实例化了一个对象并调用了一个函数:
ProjectService project;
project.f1();
现在,f1()
拨打f2()
和f2()
来电话ConnectToServer()
。所有这些功能都是CProjectT<CSoapMSXMLInetClient>
此处的问题是,调用CProjectT<CSoapMSXMLInetClient>::ConnectToServer()
而不是ProjectService::ConnectToServer()
。 (我在ConnectToServer()
个函数的第一行都有一个调试断点。基类中的一个被命中。)
为什么?
答案 0 :(得分:2)
确保使用父类中的关键字virtual
定义ConnectToServer函数。
答案 1 :(得分:1)
f2()调用ConnectToServer(),方法f2()在 COMPILE TIME 定义。因为f2()是CProject和NOT ProjectService的一部分,所以它有两种可能:
1。从CProject调用硬编码的无虚函数
2。从虚拟表中调用一个函数。
由于ConnectToServer()不是虚拟的,因此编译器将“选择”第一个选项。
如同@Ozair在第一条评论(和他的回答)中所说的那样:放置虚拟关键字将使函数成为虚拟,编译器将“选择”第二个选项,并将调用派生类。 / p>
(请注意,该函数是从f2()调用的,因此编译器无法确定该实例是基数还是派生的)
答案 2 :(得分:1)
如上所述,您需要关键字virtual
。为什么?因为在仅f2()
中定义的函数CProjectT
中,您调用函数CProjectT<CSoapMSXMLInetClient>::ConnectToServer()
。如果没有virtual
关键字,则无法知道f2()
应该调用派生方法。
如果你想测试:
#include <iostream>
using namespace std;
class Base
{
public:
void f(){g();} // Wants to call Base::g() if there's no "virtual" keyword
void g(){cout << "Base" << endl;}
// virtual void g(){cout << "Base" << endl;}
};
class Derived : public Base
{
public:
void g(){cout << "Derived" << endl;}
};
int main(int argc, char *argv[])
{
Derived d;
d.f();
}