Почему функция базового класса вызывается вместо производной? - PullRequest
0 голосов
/ 16 июня 2011

У меня есть класс:

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

Я реализовал HRESULT ConnectToServer(); функцию в этом производном классе. Затем я создал объект и вызвал функцию:

ProjectService project;
project.f1();

сейчас f1() звонит f2() и f2() звонит ConnectToServer(). Все эти функции являются членами CProjectT<CSoapMSXMLInetClient>

Проблема здесь в том, что вместо ProjectService::ConnectToServer() вызывается CProjectT<CSoapMSXMLInetClient>::ConnectToServer(). (У меня есть точка останова отладки в первой строке обеих ConnectToServer() функций. Одна из базовых классов имеет значение.)

Почему?

Ответы [ 3 ]

2 голосов
/ 16 июня 2011

Убедитесь, что функция ConnectToServer определена с ключевым словом virtual в родительском классе.

Читать о виртуальном ключевом слове в C ++

1 голос
/ 16 июня 2011

Как уже говорилось, вам нужно ключевое слово 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();
}
1 голос
/ 16 июня 2011

f2 () вызывает ConnectToServer (), а метод f2 () определяется как COMPILE TIME .поскольку f2 () является частью CProject, а не ProjectService, у него есть две возможности:
1.Вызовите жестко запрограммированную виртуальную функцию из CProject
2.вызвать функцию из виртуальной таблицы.

, поскольку ConnectToServer () не является виртуальным, компилятор «выберет» первый вариант.

, как @Ozair сказал в первом комментарии (и его ответе): установка виртуального ключевого слова сделает функцию виртуальной, а компилятор «выберет» второй вариант, и будет вызван производный класс.

(обратите внимание, что функция вызывается из f2 (), поэтому компилятор не может точно определить, является ли этот экземпляр базовым или производным)

...