在容器(container)中 使用继承(inheritance)和虚函数(virtual function)

 

本文地址: http://blog.csdn.net/caroline_wendy/article/details/16115139

 

容器不支持混合类型, 如果直接把派生类对象, 存入基类容器中, 则无法使用派生-基转换(derived-base conversion);

因为转换只能发生在指针和引用 过程中, 不能发生在 对象直接赋值, 如果是直接转换, 则会产生截断(sliced down);

即派生类部分被切除, 只留下基类部分; 所以存入容器中的派生类 输出为基类部分 的虚函数;

如果想在容器中, 进行继承, 则需要使用指针, 包括智能指针(如:shared_ptr<>), 则会输出派生类的覆写(override)版本的虚函数;

 

代码:

/*   * CppPrimer.cpp   *   *  Created on: 2013.11.12   *      Author: Caroline   */    /*eclipse cdt*/    #include <iostream>  #include <string>  #include <vector>  #include <memory>  #include <cstddef>    using namespace std;    class Quote {  public:  	Quote() = default;  	Quote (const std::string& book, double sales_price) :  		bookNo (book), price (sales_price) {}  	std::string isbn() const { return bookNo; }  	virtual double net_price (std::size_t n) const { return n* price; } //虚函数  	virtual ~Quote() = default; //动态绑定析构器  private:  	std::string bookNo;  protected: //受保护类型  	double price = 0.0;  };    class Disc_quote : public Quote { //抽象基类  public:  	Disc_quote() = default;  	Disc_quote (const std::string& book, double price, std::size_t qty, double disc) :  		Quote(book, price), quantity (qty), discount (disc) {}  	double net_price (std::size_t) const = 0; //纯虚函数  protected:  		std::size_t quantity = 0;  		double discount = 0.0;  };    class Bulk_quote final : public Disc_quote { //final限定词, 无法被继承  public:  	Bulk_quote() = default;  	Bulk_quote(const std::string& book, double p, std::size_t qty, double disc) :  		Disc_quote(book, p, qty, disc) {} //使用基类的构造器  	double net_price(std::size_t cnt) const override;  };    double Bulk_quote::net_price(std::size_t cnt) const  {  	if (cnt >= quantity)  		return cnt * (1-discount) * price;  	else  		return cnt * price;  }    double print_total(std::ostream &os, const Quote& item, std::size_t n)  {  	double ret = item.net_price(n);  	os << "ISBN: " << item.isbn() << " # sold: " << n << " total due: " << ret << std::endl;  	return ret;  }    int main (void) {    	//正常存放, 无法调用派生类的虚函数  	std::vector<Quote> basket;  	basket.push_back(Quote("CppPrimer", 50));  	basket.push_back(Bulk_quote("CppPrimer", 50, 10, .25));  	std::cout << "Bulk_quote : " << basket.back().net_price(20) << std::endl;    	//使用指针存放, 可以正确调用  	std::vector<std::shared_ptr<Quote> > sbasket;  	sbasket.push_back(std::make_shared<Quote>("CppPrimer", 50));  	sbasket.push_back(std::make_shared<Bulk_quote>("CppPrimer", 50, 10, .25));  	std::cout << "Bulk_quote : " << sbasket.back()->net_price(20) << std::endl;      	return 0;    }  


输出:

Bulk_quote : 1000  Bulk_quote : 750