c++基类对象的std::vector----派生类的运行方法
Posted
技术标签:
【中文标题】c++基类对象的std::vector----派生类的运行方法【英文标题】:c++ std::vector of base class objects ---- running method of derived class 【发布时间】:2018-02-06 19:32:58 【问题描述】:我想问一下Java中的“instanceof”之类的东西。我创建了一个简单的继承示例。我的想法是创建一个抽象类 Monster 和孩子 Skeleton 和 Zombie,但是抽象它不起作用,所以我们有 std::vectorBase 类。我将子对象推入向量中。我想调用子类的方法,但是调用的方法是基类的空方法。有没有办法做到这一点?也许在 c++ 编程中我们应该避免这种代码思维,分别使用矢量骨架和矢量僵尸来做?对不起我的英语不好。我希望你能理解我的问题。
class Monster
public:
virtual void describe() ;
;
class Skeleton : public Monster
public:
Skeleton()
~Skeleton()
void describe() override
std::cout << "I am skeleton" << std::endl;
;
class Zombie : public Monster
public:
Zombie()
~Zombie()
void describe() override
std::cout << "I am Zombie" << std::endl;
;
int main(void)
std::vector<Monster> potwory;
potwory.push_back(Skeleton());
potwory.push_back(Zombie());
Skeleton sz;
Zombie z;
potwory.push_back(sz);
potwory.push_back(z);
for (auto i = 0; i < potwory.size(); i++)
std::cout << typeid(potwory[i]).name() << std::endl; // each of them is Monster object
potwory[i].describe(); //here is calling method from base class , I want derived method.
std::cin.get();
return 0;
`
【问题讨论】:
我对你的问题有点困惑。你能试着澄清一下你需要什么吗? C++ 与 Java 的许多不同之处之一是它具有对象切片功能。 Java 避免了它,因为所有引用的行为方式都类似于 C++ 的指针。查看“对象切片”了解更多信息。 你只有一个基类对象的向量。每当你推送一个子类的对象时,你就有object slicing。要使多态性起作用,您需要引用或指针。 使用基类对象类型的std:;vector
会导致在 C++ 中称为对象切片的问题。在 SO 以及更广泛的网络中查找“对象切片”。
好的,谢谢你们。我会读到这个。
【参考方案1】:
如前所述,您遇到了切片问题,因为您只将所有对象的 Monster
部分存储在向量中。
您可以使用 std::vector<Monster*>
或从 c++11 std::vector<std::unique_ptr<Monster>>
开始在向量中存储指向 Monster
的指针/unique_ptr。存储指向实际对象的指针可以减轻切片,因为对象不直接存储在向量中,而只是对堆上实际对象的引用,就像 Java 默认情况下所做的那样。
如果你真的需要价值语义,你应该看看boost.polycollection,但恕我直言,这是一个相当高级的话题。
【讨论】:
【参考方案2】:感谢您的回答。我无法为您加分以寻求帮助,因为我是 "stack" 上的新手。我读到了这个问题,并写了一个解决方案。如果有人需要这个。
#include <iostream>
#include <vector>
#include <memory>
class Monster
public:
virtual void describe() ;
virtual std::unique_ptr<Monster> copy_class()
return std::unique_ptr<Monster>(std::make_unique<Monster>());
;
class Skeleton : public Monster
protected:
const int life = 100;
public:
Skeleton()
~Skeleton()
void describe() override final
std::cout << "I am skeleton" << std::endl;
std::unique_ptr<Monster> copy_class() override
return std::unique_ptr<Monster>(std::make_unique<Skeleton>());
;
class Zombie : public Monster
public:
Zombie()
~Zombie()
void describe() override
std::cout << "I am zombie" << std::endl;
std::unique_ptr<Monster> copy_class() override
return std::unique_ptr<Monster>(std::make_unique<Zombie>());
;
class UpgradeSkeleton final: public Skeleton
public:
UpgradeSkeleton()
~UpgradeSkeleton()
std::unique_ptr<Monster> copy_class() override return std::unique_ptr<Monster>(std::make_unique<UpgradeSkeleton>());
;
int main(void)
std::vector<std::unique_ptr<Monster>> monsters;
Skeleton s;
Zombie z;
UpgradeSkeleton us;
monsters.push_back(std::unique_ptr<Monster>(s.copy_class()));
monsters.push_back(std::unique_ptr<Monster>(z.copy_class()));
monsters.push_back(std::unique_ptr<Monster>(us.copy_class()));
for (auto &p : monsters)
p->describe();
std::cin.get();
return 0;
【讨论】:
以上是关于c++基类对象的std::vector----派生类的运行方法的主要内容,如果未能解决你的问题,请参考以下文章