在基类c ++的向量中从派生类调用虚方法

时间:2013-07-01 02:26:21

标签: c++ xcode c++11

在类BaseClass中我有一个公共函数:

virtual void Call(){};

在派生类Archer中我有函数:

void Call(){ cout << "whatever" << endl; };

我也有一个矢量设置:

vector<BaseClass> classes;

其中我推送了从BaseClass派生的3个类。问题似乎(对我来说,我可能是错的)是我从BaseClass的引用调用Call(),即使我通过类似的方法将它们推送到向量中:

BaseClass Player::CharChoice(string character)
{
    if(character == "Archer") return *new Archer();
    else if(character == "Knight") return *new Knight();
    else if(character == "Sorcerer") return *new Sorcerer();
    else cerr << "CHARACTER NOT DEFINED" << endl;
};

for(int c = 0; c < chars.size(); c++)
{
    classes.push_back(CharChoice(chars[c]));
}

如果我改为设置变量,例如:

Archer *archer = new Archer();

并调用Call(),它的工作原理我想要的。我是C ++的新手,无法想出解决方案。

1 个答案:

答案 0 :(得分:3)

当您在堆栈而不是堆上创建对象时,大部分继承值都会丢失。虚函数是你失去的东西之一,如果你想让虚函数调用正确的函数你必须将对象作为指针或引用传递,并使用new来创建它。

Base * b = new Derived();    // or  
Base & b = * new Derived();  

向量必须存储引用或指针。

vector<BaseClass*> classes;
vector<BaseClass&> classes;

根据大众需求,处理此问题的最简单方法是std::shared_ptr

vector<shared_ptr<BaseClass>> classes;

其中一个会像这样创建:

shared_ptr<BaseClass> ptr(new BaseClass);

基本上,shared_ptr将处理令人讨厌的内存管理任务

如果您需要多个ptr到同一个对象,那么

shared_ptr很好,如果不是,您可以使用std::unique_ptr

vector<unique_ptr<BaseClass>> classes;

像这样创建:

unique_ptr<BaseClass> ptr(new BaseClass);

正如您所看到的,语法与shared_ptr非常相似,因此转换很容易