C++ Primer 5th笔记(chap 15 OOP)构造函数和拷贝控制
1. 虛析構(gòu)函數(shù)
基類通常應(yīng)該定義一個(gè)虛析構(gòu)函數(shù)。
class Quote { public:// virtual destructor needed if a base pointer pointing to a// derived object is deletedvirtual ~Quote() = default; // dynamic binding for the destructor };如果基類的析構(gòu)函數(shù)不是虛函數(shù),則delete一個(gè)指向派生類對(duì)象的基類指針會(huì)產(chǎn)生未定義的結(jié)果。
Quote *itemP = new Quote; // same static and dynamic type delete itemP; // destructor for Quote called itemP = new Bulk_quote; // static and dynamic types differ delete itemP; // destructor for Bulk_quote called虛析構(gòu)函數(shù)會(huì)阻止編譯器為類合成移動(dòng)操作(有析構(gòu)就有拷貝構(gòu)造和拷貝賦值,那么編譯器就不會(huì)合成移到操作了)
2. 合成拷貝控制與繼承
基類或派生類的合成拷貝控制成員的行為和其他合成的構(gòu)造函數(shù)、賦值運(yùn)算符或析構(gòu)函數(shù)類似:對(duì)類本身的成員依次進(jìn)行初始化、賦值或銷毀的操作。如果成員是一個(gè)對(duì)象,還使用對(duì)象的初始化、賦值或銷毀的操作。
基類沒有移到操作那么它的派生類也沒有。
2.1 派生類中的刪除拷貝控制與基類的關(guān)系
● 如果基類中的默認(rèn)構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)、拷貝賦值運(yùn)算符或析構(gòu)函數(shù)是被刪除的或者不可訪問的函數(shù),則派生類中對(duì)應(yīng)的成員也會(huì)是被刪除的。因?yàn)榫幾g器不能使用基類成員來執(zhí)行派生類對(duì)象中基類部分的構(gòu)造、賦值或銷毀操作。
● 如果基類的析構(gòu)函數(shù)是被刪除的或者不可訪問的,則派生類中合成的默認(rèn)和拷貝構(gòu)造函數(shù)也會(huì)是被刪除的。因?yàn)榫幾g器無法銷毀派生類對(duì)象中的基類部分。
● 編譯器不會(huì)合成一個(gè)被刪除的移動(dòng)操作。當(dāng)我們使用=default請(qǐng)求一個(gè)移動(dòng)操作時(shí),如果基類中對(duì)應(yīng)的操作是被刪除的或者不可訪問的,則派生類中的操作也會(huì)是被刪除的。因?yàn)榕缮悓?duì)象中的基類部分不能移動(dòng)。同樣,如果基類的析構(gòu)函數(shù)是被刪除的或者不可訪問的,則派生類的移動(dòng)構(gòu)造函數(shù)也會(huì)是被刪除的。
在實(shí)際編程中,如果基類沒有默認(rèn)、拷貝或移動(dòng)構(gòu)造函數(shù),則一般情況下派生類也不會(huì)定義相應(yīng)的操作。
2.2. 移到操作和繼承
因?yàn)榛惾鄙僖苿?dòng)操作會(huì)阻止編譯器為派生類合成自己的移動(dòng)操作,所以當(dāng)我們確實(shí)需要執(zhí)行移動(dòng)操作時(shí),應(yīng)該首先在基類中進(jìn)行定義。
class Quote{public:Quote() = default;Quote(const string& s, double sales_price) :bookNo(s), price(sales_price) {}Quote(const Quote&);//拷貝構(gòu)造函數(shù)Quote& operator=(const Quote&);//拷貝賦值運(yùn)算符Quote(Quote&&);//移動(dòng)構(gòu)造函數(shù)Quote& operator=(Quote&&);//移動(dòng)賦值運(yùn)算string isbn() const;virtual double net_price(size_t n) const;//虛函數(shù)virtual void debug() const;virtual ~Quote() {}//對(duì)析構(gòu)函數(shù)進(jìn)行動(dòng)態(tài)綁定private:string bookNo;protected:double price = 0.0;};ostream& 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;item.debug();return os;}string Quote::isbn() const{return bookNo;}double Quote::net_price(size_t n) const{return n * price;}void Quote::debug() const{cout << "i am quote:" << bookNo << " " << price << endl;}Quote::Quote(const Quote& q){cout << "hello i am 拷貝構(gòu)造函數(shù)Quote" << endl;bookNo = q.bookNo;price = q.price;}Quote& Quote::operator=(const Quote& q){cout << "hello i am 拷貝賦值運(yùn)算符Quote" << endl;if (this != &q){bookNo = q.bookNo;price = q.price;}return *this;}Quote::Quote(Quote&& q){cout << "hello i am 移動(dòng)構(gòu)造函數(shù)Quote" << endl;bookNo = std::move(q.bookNo);price = std::move(q.price);q.bookNo = "";q.price = 0;}Quote& Quote::operator=(Quote&& q){cout << "hello i am 移動(dòng)賦值運(yùn)算符Quote" << endl;if (this != &q){bookNo = std::move(q.bookNo);price = std::move(q.price);q.bookNo = "";q.price = 0;}return *this;}void test() {Quote test("cuinan", 100);Quote test1(test);Quote test2;test2 = test;Quote test3(std::move(test));test2 = std::move(test);}輸出結(jié)果:
hello i am 拷貝構(gòu)造函數(shù)Quote
hello i am 拷貝賦值運(yùn)算符Quote
hello i am 移動(dòng)構(gòu)造函數(shù)Quote
hello i am 移動(dòng)賦值運(yùn)算符Quote
【引用】
[1] 代碼oopTest.h
總結(jié)
以上是生活随笔為你收集整理的C++ Primer 5th笔记(chap 15 OOP)构造函数和拷贝控制的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ Primer 5th笔记(cha
- 下一篇: C++ Primer 5th笔记(cha