#include "../head.h" class Quote { public: Quote() {cout << "default constructing Quote" << endl;}; Quote(const string &book, double sales_price) : bookNo(book), price(sales_price) { cout << "Quote:cosntructor taking 2 parameters" << endl; } Quote(const Quote &q) : bookNo(q.bookNo), price(q.price) { cout << "Quote:copy constructing Quote" << endl; } Quote& operator=(const Quote &rhs) { bookNo = rhs.bookNo; price = rhs.price; cout << "Quote:copy=()" << endl; return *this; } Quote(const Quote &&q) noexcept : bookNo(move(q.bookNo)), price(move(q.price)) { cout << "Quote:move constructing" << endl; } Quote& operator=(const Quote &&rhs) { bookNo = move(rhs.bookNo); price = move(rhs.price); cout << "Quote:move=()" << endl; return *this; } string isbn() const {return bookNo;} virtual double net_price(size_t n) const {return n * price;} virtual ~Quote() {cout << "destructing Quote" << endl;}; protected: double price = 0.0; private: string bookNo; }; class Disc_quote : public Quote { public: Disc_quote() {cout << "default constructing Disc_quote" << endl;} Disc_quote(const string &book, double price, size_t qty, double disc) : Quote(book, price), quantity(qty), discount(disc) { cout << "Disc_quote:constructor taking 4 parameters" << endl; } Disc_quote(const Disc_quote &q) : Quote(q) { cout << "Disc_quote:copy constructing Disc_quote" << endl; } Disc_quote& operator=(const Disc_quote &rhs) { Quote::operator=(rhs); cout << "Disc_quote:copy=()" << endl; return *this; } Disc_quote(const Disc_quote &&q) noexcept : Quote(move(q)) { cout << "Disc_quote:move constructing" << endl; } Disc_quote& operator=(const Disc_quote &&rhs) { Quote::operator=(move(rhs)); cout << "Disc_quote:move=()" << endl; return *this; } double net_price(size_t n) const override { if (n >= quantity) return n * (1 - discount) * price; else return n * price; } ~Disc_quote() {cout << "destructing Disc_quote" << endl;} protected: size_t quantity = 0; double discount = 0.0; }; void print_total(ostream &os, const Quote &item, size_t n) { double ret = item.net_price(n); os << "ISBN: " << item.isbn() << "# sold: " << n << "total due: " << ret << endl; } int main(int argc, char** argv) { Quote item1("hello", 10); Disc_quote item2("hello", 10, 5, 0.1); cout << "<==copy constructor test ==>" << endl; Disc_quote item3(item2); Disc_quote item4; item4 = item3; cout << "<==move constructor test ==>" << endl; Disc_quote item5(move(item2)); Disc_quote item6; item6 = move(item5); cout << "<==destructing test ==>" << endl; return 0; }
Quote:cosntructor taking 2 parameters Quote:cosntructor taking 2 parameters Disc_quote:constructor taking 4 parameters <==copy constructor test ==> Quote:copy constructing Quote Disc_quote:copy constructing Disc_quote default constructing Quote default constructing Disc_quote Quote:copy=() Disc_quote:copy=() <==move constructor test ==> Quote:move constructing Disc_quote:move constructing default constructing Quote default constructing Disc_quote Quote:move=() Disc_quote:move=() <==destructing test ==> destructing Disc_quote destructing Quote destructing Disc_quote destructing Quote destructing Disc_quote destructing Quote destructing Disc_quote destructing Quote destructing Disc_quote destructing Quote destructing Quote
這是《C++ primer》
15-26
的題,主要就是爲了測試派生類拷貝控制操做的行爲,實驗結果與預期相同ide
1 派生類的默認構造函數會先運行基類的默認構造函數,將基類中的數據成員初始化,而後執行本身的默認構造函數,將數據成員初始化
2 派生類使用拷貝構造函數時會先運行基類的拷貝構造函數,而後再運行本身的拷貝構造函數,對於拷貝賦值運算符、移動構造函數、移動賦值運算符也都是相似的操做
3 派生類銷燬時先執行本身的析構函數,再執行基類的析構函數函數