说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

vector&父类子类的问题

编辑:说三道四文库 发布时间:2018-07-18 05:19
HTML文档下载 WORD文档下载 PDF文档下载
我在使用vector来存放类的实例后,在方法中调用的时候,出错,请各位大虾,帮帮忙


定义:
std::vector<Record> data;

//其中Record是我自己定义的类,它本身是一个父类,他还有几个子类,如FillRecord

现在我定义一个方法
int compileFillRecord( FillRecord record )

调用的时候,出了问题

int i = compileFillRecord( data.at(0) );
//此处的data就是上面定义的vector,data中存放的就是Record的子类FillRecord,难道
我这样调用不行吗,问题出在哪里??
还是因为data.at()返回的是一个引用,是我调用的方法不对吗??

急!!请帮助!!thanks
向下影射需要用强转型
int i = compileFillRecord( static_cast<FillRecord>(data.at(0)) );
对象类型是不参相互转换的(除非定义了相应的类型转换操作符或是copy constructor),只在对象指针或对象引用类型才可以自动“向上映射”。而向下映射则必须用强制类型转换。

你这里范了几个错误:
1:不能用vector<Record>去存放Record的衍生类对象,即使存进去了,也会变成了Record对象而不再是原来的类型了(vector中存储的都是调用Record的构造函数生成的对象,只能是Record)。如果你想要让它可以存储衍生类的对象,应该让它存储指针类型(用vector<Record*>,更好的方法是使用vector<boost::shared_ptr<Record>>)。

2:不能把一个对象传给要求其基类对象作为参数的对象(连类型转换都不能用),如果要这样做还是必须使用指针或引用,还要做类型转换。也可以在调用函数时转换:
 
FillRecord *temp = dynamic_cast<FillRecord*>(data.at(0));//假设你用的是vector<Record*>
if (FillRecord != NULL)
  complileFillRecord(*temp);

如果你可以确定data.at(0)一定是个FillRecord并且Record是FillRecord的第一个公共非虚基类,也可以用static_cast转换以提高效率。
在vector中保存指针,然后将record中加入虚拟函数。
换成
std::vector<Record&> data;
或者
std::vector<Record*> data;
由于vector的元素为record的类型,所以添加record派生类型对象时会发生对象切片现象。
同时,在函数调用过程中,需要fillrecord类型对象,而vector中对象的实际类型均不适该类型,也不能转化为该类型(超类对象不能转化为子类对象)。
另外就是频繁的拷贝复制对象会降低系统效率,建议采用wenddydd的方法。
More Effictive C++ Item 3
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘