200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > C++ Primer 5th笔记(chap 15 OOP)构造函数和拷贝控制

C++ Primer 5th笔记(chap 15 OOP)构造函数和拷贝控制

时间:2018-08-18 01:04:06

相关推荐

C++ Primer 5th笔记(chap 15 OOP)构造函数和拷贝控制

1. 虚析构函数

基类通常应该定义一个虚析构函数。

class Quote{public:// virtual destructor needed if a base pointer pointing to a// derived object is deletedvirtual ~Quote() = default; // dynamic binding for the destructor};

如果基类的析构函数不是虚函数,则delete一个指向派生类对象的基类指针会产生未定义的结果。

Quote *itemP = new Quote; // same static and dynamic typedelete itemP;// destructor for Quote calleditemP = new Bulk_quote;// static and dynamic types differdelete itemP;// destructor for Bulk_quote called

虚析构函数会阻止编译器为类合成移动操作(有析构就有拷贝构造和拷贝赋值,那么编译器就不会合成移到操作了)

2. 合成拷贝控制与继承

基类或派生类的合成拷贝控制成员的行为和其他合成的构造函数、赋值运算符或析构函数类似:对类本身的成员依次进行初始化、赋值或销毁的操作。如果成员是一个对象,还使用对象的初始化、赋值或销毁的操作。

基类没有移到操作那么它的派生类也没有。

2.1 派生类中的删除拷贝控制与基类的关系

● 如果基类中的默认构造函数、拷贝构造函数、拷贝赋值运算符或析构函数是被删除的或者不可访问的函数,则派生类中对应的成员也会是被删除的。因为编译器不能使用基类成员来执行派生类对象中基类部分的构造、赋值或销毁操作。

● 如果基类的析构函数是被删除的或者不可访问的,则派生类中合成的默认和拷贝构造函数也会是被删除的。因为编译器无法销毁派生类对象中的基类部分。

● 编译器不会合成一个被删除的移动操作。当我们使用=default请求一个移动操作时,如果基类中对应的操作是被删除的或者不可访问的,则派生类中的操作也会是被删除的。因为派生类对象中的基类部分不能移动。同样,如果基类的析构函数是被删除的或者不可访问的,则派生类的移动构造函数也会是被删除的。

class B {public:B();B(const B&) = delete;};class D : public B{}; void test(){D d;//ok//D d2(d);//error//D d3(std::move(d));//隐式使用D的被删除的拷贝构造函数}

在实际编程中,如果基类没有默认、拷贝或移动构造函数,则一般情况下派生类也不会定义相应的操作。

2.2. 移到操作和继承

因为基类缺少移动操作会阻止编译器为派生类合成自己的移动操作,所以当我们确实需要执行移动操作时,应该首先在基类中进行定义。

class Quote{public:Quote() = default;Quote(const string& s, double sales_price) :bookNo(s), price(sales_price) {}Quote(const Quote&);//拷贝构造函数Quote& operator=(const Quote&);//拷贝赋值运算符Quote(Quote&&);//移动构造函数Quote& operator=(Quote&&);//移动赋值运算string isbn() const;virtual double net_price(size_t n) const;//虚函数virtual void debug() const;virtual ~Quote() {}//对析构函数进行动态绑定private:string bookNo;protected:double price = 0.0;};ostream& print_total(ostream& os, const Quote& item, size_t n){double ret = _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 拷贝构造函数Quote" << endl;bookNo = q.bookNo;price = q.price;}Quote& Quote::operator=(const Quote& q){cout << "hello i am 拷贝赋值运算符Quote" << endl;if (this != &q){bookNo = q.bookNo;price = q.price;}return *this;}Quote::Quote(Quote&& q){cout << "hello i am 移动构造函数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 移动赋值运算符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);}

输出结果:

hello i am 拷贝构造函数Quote

hello i am 拷贝赋值运算符Quote

hello i am 移动构造函数Quote

hello i am 移动赋值运算符Quote

【引用】

[1] 代码oopTest.h

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。