容器与继承

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

例如:

#include
#include
#include
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 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
#include
using namespace std;

char  main()
{
	vector Vec;
	string isbn;
	double price,qty,discounty;
	cout<<"Enter some child objects(Ctrl+Z to end):"<>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::iterator iter=Vec.begin();iter!=Vec.end();++iter)
		sum+=(*iter)->net_price(10);
	cout<<"summation of net price:"<::iterator it=Vec.begin();it!=Vec.end();++it)
		delete *it;
	getchar();
}

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

你可能感兴趣的:(C/C++语言)