2015-01-23 2 views
1

Может кто-нибудь, пожалуйста, помогите мне в том, что я делаю неправильно? Всегда вызывается указатель базового класса! Я пытаюсь создать карту пользовательских объектов класса. Пробовал и поиск и индексирование напрямую, но тот же результат!Виртуальная функция, почему здесь называется функция базового класса?

#include "stdafx.h" 
#include <iostream> 
#include <string> 
#include <Map> 
#include <algorithm> 

class Command 
{ 
public: 
    virtual int execute(std::string *args) { std::cout << "Base called ! ERROR!\n"; return -1; } 
}; 

class ShowNames : public Command 
{ 
public: 
    int execute(std::string names) 
    { 
     std::cout << names; 
     return 0; 
    } 
}; 

class ShowNos : public Command 
{ 
public: 
    int execute(std::string Nos) 
    { 
     std::cout << Nos; 
     return 0; 
    } 
}; 

typedef std::map<std::string, Command*> CmdList; 

CmdList buildMaps() 
{ 
    CmdList c1; 
    ShowNames s1; 
    ShowNos n1; 

    c1["names"] = new ShowNames(); 
    c1["nos"] = new ShowNos(); 

    //c1.find("names") 

    return c1; 
} 

void testCommandList() 
{ 
    CmdList commands; 
    Command *c1; 
    commands = buildMaps(); 

    std::string cmd,args; 
    std::cout << "Enter your command: "; 
    std::cin >> cmd; 
    std::cout << "Enter args for the command: "; 
    std::cin >> args; 

    auto it = commands.find(cmd); 
    if (it != commands.end()) 
    { 
     it->second->execute(&args); 
    } 
    else 
    { 
     std::cout << "Command not found, try again\n"; 
    } 

} 

ответ

7

Вы не переопределяете базовую функцию в производных классах, вы объявляете новые функции. Сравните типы функций:

int Command::execute(std::string *args) 
int ShowNames::execute(std::string names) 
int ShowNos::execute(std::string Nos) 

(Унифицированные, чтобы сделать его более очевидным)

Чтобы переопределить функцию базового класса, вы должны соответствовать подписи точно (для ковариантного возвращаемого типа, за исключением, если это необходимо). Поэтому измените подписи, чтобы они были одинаковыми. Конечно, какой из них зависит от вашей проблемной области.

Именно поэтому C++ 11 представил зарезервированное слово override, которое вы можете использовать в виртуальной функции, которую вы намерены переопределить для функции базового класса. Тогда это приведет к ошибке компиляции, если это не так. Если у вас есть доступ к C++ 11, вы должны всегда использовать его, когда вы имеете в виду это, как это:

class ShowNames : public Command 
{ 
public: 
    int execute(std::string names) override 
    { 
     std::cout << names; 
     return 0; 
    } 
}; 

Это сразу сказать, что это не отменяет каких-либо функций базового класса, и вы бы быть в гораздо лучшем положении, чтобы начать расследование, почему.

+0

Не знал об этом, спасибо за информацию! – vinit

4

Вы никогда не перезаписываете свой метод базового класса.

virtual int execute(std::string *args) 

Это подпись. Вам нужно придерживаться этого, а не менять его.

+0

Спасибо, что исправил это ... как глупо от меня !! – vinit

Смежные вопросы