我知道这可能是一个非常简单的问题,但它确实让我困惑了几天。我尝试将派生类存储在存储基类类型的标准std:vector中。 如果我使基(父)类成为纯虚拟类。我无法在向量中存储派生类。 如果我实现了基(父)类的getName()方法。我可以成功建立。但是在对矢量进行迭代时。它失去了多态性......
#include "stdafx.h"
#include <string>
#include <iostream>
#include <vector>
using namespace std;
class father{
public:
//virtual string getName() = 0; //If uncomment here. push_back(c1) will induce build error.
virtual string getName(){ return "father";}
};
class child1 : public father{
public:
virtual string getName(){
return "child1";
}
};
class child2 : public father{
public:
virtual string getName(){
return "child2";
}
};
class child3 : public father{
public:
virtual string getName(){
return "child3";
}
};
int _tmain(int argc, _TCHAR* argv[])
{
child1 c1;
child2 c2;
child3 c3;
cout<< "c1 " << sizeof(c1) << endl;
cout<< "c2 " << sizeof(c2) << endl;
cout<< "c3 " << sizeof(c3) << endl;
vector<father> v;
v.push_back(c1); //build error if Father is pure virtual class
v.push_back(c2); //build error
v.push_back(c3); //build error
for(std::vector<father>::iterator it = v.begin(); it != v.end(); ++it)
{
cout << "I'm " << it->getName() << endl; //lose polymorphism
}
return 0;
}
总结两个问题: 1.为什么将base(father)类定义为纯虚拟类。我无法在向量中存储派生类? 2.为什么当我再次从矢量中获得课程时。它失去了多态性?
提前感谢您的帮助。真的很感激!
答案 0 :(得分:1)
这是因为在C ++中,向量存储father
,它本身就是一个对象。在Java等其他语言中,您将隐式存储对原始对象(子项)的引用。
当构造存储在向量内的father
对象时,切片复制的对象。
如果你想在C ++中使用类似于Java的东西,请使用:
std::vector<std::shared_ptr<father>> v;
答案 1 :(得分:0)
- 为什么将base(father)类定义为纯虚拟类。我不能在vector中存储派生类?
醇>
您声明了father
的向量,如果father
是一个abstrcat类,则无法实例化它。即使您将child
的实例放入其中,也会将其复制(切片)为father
。
- 为什么当我再次从矢量中获得课程时。它失去了多态性?
醇>
如果要保持多态性,则必须通过指针或引用访问对象。在您的情况下,最好使用智能指针而不是原始指针,例如:
vector<shared_ptr<father>> v;
v.push_back(new child1);
v.push_back(new child2);
v.push_back(new child3);
for (auto it = v.begin(); it != v.end(); ++it)
{
cout << "I'm " << (*it)->getName() << endl;
}