从基类c ++的向量中的派生类调用虚拟方法[重复]
Posted
技术标签:
【中文标题】从基类c ++的向量中的派生类调用虚拟方法[重复]【英文标题】:Calling virtual method from derived class in vector of base class c++ [duplicate] 【发布时间】:2013-07-01 02:26:21 【问题描述】:在 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++ 还很陌生,无法想出解决方案。
【问题讨论】:
多态性仅适用于指针和引用。但是您将BaseClass
作为来自CharChoice
的副本返回,并且当您将其推送到向量时会制作另一个副本。每个副本都将对象切回 BaseClass
对象。
*new T()
几乎总是一个错误。使用智能指针。
【参考方案1】:
当您在堆栈而不是堆上创建对象时,继承的大部分价值都会丢失。虚函数是您丢失的东西之一,如果您希望虚函数调用正确的函数,您必须将对象作为指针或引用传递并使用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 非常相似,因此转换很容易
【讨论】:
鉴于该问题被标记为 C++11,我发现在答案中包含有关智能指针的词非常可取。 @jogojapan 我试试看 你想更喜欢unique_ptr
而不是shared_ptr
。
@Griwes 你能解释一下原因吗?
@aaronman,性能低于shared_ptr
。和适当的语义。如果所有权是唯一的,请始终使用unique_ptr
,并且除非明确标记,否则始终假定唯一的所有权。以上是关于从基类c ++的向量中的派生类调用虚拟方法[重复]的主要内容,如果未能解决你的问题,请参考以下文章
派生自抽象基类并调用另一个类中的方法的 C++ 包装类,该类也派生自抽象基类