为什么调用基类函数而不是派生函数?

时间:2011-06-16 12:39:00

标签: c++ inheritance override

我有一个班级:

class ProjectService : public CProjectT<CSoapMSXMLInetClient>
{
...
}

我在此派生类中实现了HRESULT ConnectToServer();函数。然后我实例化了一个对象并调用了一个函数:

ProjectService project;
project.f1();

现在,f1()拨打f2()f2()来电话ConnectToServer()。所有这些功能都是CProjectT<CSoapMSXMLInetClient>

的成员

此处的问题是,调用CProjectT<CSoapMSXMLInetClient>::ConnectToServer()而不是ProjectService::ConnectToServer()。 (我在ConnectToServer()个函数的第一行都有一个调试断点。基类中的一个被命中。)

为什么?

3 个答案:

答案 0 :(得分:2)

确保使用父类中的关键字virtual定义ConnectToServer函数。

了解virtual keyword in C++

答案 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();
}