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