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

在容器(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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ElminsterAumar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值