有人可以帮我解决我做错的事吗?始终调用基类指针!我正在尝试制作自定义类对象的Map。通过直接查找和索引来尝试,但结果相同!
#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";
}
}
答案 0 :(得分: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;
}
};
这会立即告诉您它不会覆盖任何基类函数,并且您可以更好地开始调查原因。
答案 1 :(得分:4)
你永远不会覆盖你的基类方法。
virtual int execute(std::string *args)
这是签名。你需要坚持下去,而不是改变它。