容器与继承

来源:互联网 发布:拼立得mac版 编辑:程序博客网 时间:2024/05/21 10:09

我们希望使用容器(或内置数组)保存因继承而相关联的对象。但是,对象不是多态的,这一事实对将容器用于继承层次中的类型有影响。

例如:

#include<iostream>#include<string>#include<stdlib.h>using namespace std;class base{public:base(const string &book="",double sales_price=0.0):isbn(book), price(sales_price){}string book()const{return isbn;}//返回特定购书量的总价格//派生类将重载该函数以应对不同的折扣策略virtual double net_price(rsize_t n)const{return n*price;}//复制控制成员base(const base& ib):isbn(ib.isbn),price(ib.price){}//重载操作符base& operator=(const base& rhs){isbn=rhs.isbn;price=rhs.price;return *this;}virtual ~base(){}private:string isbn;protected:double price;};class child:public base{public:child(const string& book="", double sales_price=0.0,size_t qty = 0, double disc_rate = 0.0):base(book, sales_price),min_qut(qty), discount(disc_rate) {}//重定义基类版本double net_price(rsize_t cnt)const{if(cnt>=min_qut){return cnt*discount*price;}else return cnt*price;}//复制控制成员child(const child& b):base(b),min_qut(b.min_qut),discount(b.discount){}child& operator=(const child& rhs){if(this!=&rhs)base::operator=(rhs);min_qut=rhs.min_qut;discount=rhs.discount;return *this;}virtual ~child(){}protected:int min_qut;          //可打折的最小购买量double discount;       //折扣率};

假如我们定义

multiset<Item_base> basket;
Item_base base;
Bulk_item bulk;

basket.insert(base);   // ok: add copy of base to basket

basket.insert(bulk);   // ok: but bulk sliced down to its base part

则加入派生类型的对象时,只将对象的基类部分保存在容器中。记住,将派生类对象复制到基类对象时,派生类对象将被切掉。

容器中的元素是 Item_base 对象,无论元素是否作为 Bulk_item 对象的副本而建立,当计算元素的 net_price 时,元素将按不打折定价。一旦对象放入了 multiset,它就不再是派生类对象了。

解决办法:

#include"标头.h"#include<utility>#include<vector>using namespace std;char  main(){vector<base*> Vec;string isbn;double price,qty,discounty;cout<<"Enter some child objects(Ctrl+Z to end):"<<endl;while(cin>>isbn>>price>>qty>>discounty){child *p=new child(isbn,price,qty,discounty);Vec.push_back(p);//Vec.push_back(child(isbn,price,qty,discounty));}double sum=0.0;for(vector<base*>::iterator iter=Vec.begin();iter!=Vec.end();++iter)sum+=(*iter)->net_price(10);cout<<"summation of net price:"<<sum<<endl;for(vector<base*>::iterator it=Vec.begin();it!=Vec.end();++it)delete *it;getchar();}

这是唯一可行的选择可能是使用容器保存对象的指针。这个策略可行,但代价是需要用户面对管理对象和指针的问题,用户必须保证只要容器存在,被指向的对象就存在。如果对象是动态分配的,用户必须保证在容器消失时适当地释放对

原创粉丝点击