容器不支持混合類型, 如果直接把派生類對象, 存入基類容器中, 則無法使用派生-基轉換(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
作者:csdn博客 Spike_King