C++ Primer 学习笔记_70_面向对象编程 --纯虚函数、容器与继承
来源:互联网 发布:巨杉数据库笔试 编辑:程序博客网 时间:2024/04/28 16:04
面向对象编程
--纯虚函数、容器与继承
I.纯虚函数
在函数形参后面写上 =0 以指定纯虚函数:
- class Disc_item : public Item_base
- {
- public:
- double net_price(size_t) const = 0; //指定纯虚函数
- };
将函数定义为纯虚函数能够说明,该函数为后代类型提供了可以覆盖的接口,但是这个类的版本绝不会调用。重要的是,用户将不能创建Disc_item类型的对象。
- Disc_item discount; //Error
- Bulk_item bulk; //OK
- //因为Bulk_item类继承自 Disc_item 类,并且重写了 net_price 函数
【注解】
含有(或继承)一个或多个纯虚函数的类是抽象基类。除了作为抽象基类的派生类的对象组成部分,不能创建抽象类型的对象。
- //P503 习题15.26/27
- class Disc_item : public Item_base
- {
- public:
- Disc_item(const std::string &book = "",
- double sales_price = 0.0,
- std::size_t qty = 0,
- double disc_rate = 0.0):
- Item_base(book,sales_price),quantity(qty),discount(disc_rate) {}
- double net_price(size_t) const = 0;
- protected:
- std::size_t quantity;
- double discount;
- };
- //...
- int main()
- {
- Disc_item item;
- }
错误信息:
II.容器与继承
我们希望使用容器(或内置数组)保存因继承而相关联的对象。但是,对象不是多态的,这一事实对将容器用于继承层次中的类型有影响。
如果定义multiset保存基类类型的对象:
- multiset<Item_base> basket;
- Item_base base;
- Bulk_item bulk;
- basket.insert(base); //OK
- basket.insert(bulk); //OK:但是,bulk的派生类部分将被无情的“切割”掉
则加入派生类型的对象时,只将对象的基类部分保存在容器中。谨记:将派生类对象复制到基类对象时,派生类对象将被切掉。因此,一旦放入了multiset,他就不再是派生类对象了。
【小心地雷】
因为派生类对象在赋值给基类对象时会被“切掉”,所以容器与通过继承相关的类型不能很好的融合。
不能通过定义容器保存派生类对象来解决这个问题。在这种情况下,不能将Item_base对象放入容器—— 没有从基类类型到派生类型的标准转换。可以显式地将基类对象强制转换为派生类对象并将结果对象加入容器,但是,如果这样做,当试图使用这样的元素时,会产生大问题:在这种情况下,元素可以当作派生类对象对待,但派生类部分的成员将是未初始化的。
唯一可行的选择可能是使用容器保存对象的指针。这个策略可行,但代价是需要用户面对管理对象和指针的问题,用户必须保证只要容器存在,被指向的对象就存在。如果对象是动态分配的,用户必须保证在容器消失时适当地释放对象。
- //P504 习题15.28
- int main()
- {
- vector<Item_base> itemVec;
- for (size_t i = 0; i != 10; ++i)
- {
- Bulk_item item("C++ Primer",6,5,0.5);
- itemVec.push_back(item);
- }
- double sum = 0;
- for (vector<Item_base>::iterator iter = itemVec.begin();
- iter != itemVec.end(); ++iter)
- {
- sum += iter -> net_price(10); //调用Item_base:: net_price
- }
- cout << sum << endl; //output 600
- }
- //习题15.29
- int main()
- {
- vector<Item_base *> itemVec;
- for (size_t i = 0; i != 10; ++i)
- {
- Bulk_item *item = new Bulk_item("C++ Primer",6,5,0.5);
- itemVec.push_back(item);
- }
- double sum = 0;
- for (vector<Item_base *>::iterator iter = itemVec.begin();
- iter != itemVec.end(); ++iter)
- {
- sum += (*iter) -> net_price(10);
- }
- cout << sum << endl; //output 300
- //显式释放动态分配的内存
- for (vector<Item_base *>::iterator iter = itemVec.begin();
- iter != itemVec.end(); ++iter)
- {
- delete *iter;
- }
- }
0 0
- C++ Primer 学习笔记_70_面向对象编程 --纯虚函数、容器与继承
- C++ Primer 学习笔记_70_面向对象编程 -纯虚函数、器皿与继承
- C++ Primer 学习笔记_67_面向对象编程 -变换与继承、复制控制与继承
- C++ Primer 学习笔记_71_面向对象编程 --句柄类与继承
- C++ Primer 学习笔记_71_面向对象编程 --句柄类与继承
- C++ Primer 学习笔记_72_面向对象编程 -句柄类与继承[续]
- C++学习笔记53——纯虚函数与继承中的容器
- 【c++primer——15】面向对象编程01——虚函数与默认实参
- C++ Primer 学习笔记_69_面向对象编程 -继承景况下的类作用域
- C++primer学习:面象对象程序设计(5):容器与继承
- c++ primer学习之-----面向对象编程(继承与动态绑定)
- C++primer学习:面向对象程序设计(3):访问控制与继承
- <C++Primer>第四版 阅读笔记 第四部分 “面向对象编程与泛型编程”
- 面向对象编程与泛型编程---C++primer读书笔记
- C++ Primer 学习笔记_68_面向对象编程 -构造函数跟复制控制[续]
- C++Primer学习笔记第十五章(15/18)类 面向对象编程
- C++ Primer学习笔记——$15 面向对象编程
- C++ Primer学习笔记——$15 面向对象编程
- 爱
- win7 打开E盘显示 “改程序没有与之关联的程序执行该操作”
- OTT
- C++ Primer 学习笔记_71_面向对象编程 --句柄类与继承
- 露打三更
- C++ Primer 学习笔记_70_面向对象编程 --纯虚函数、容器与继承
- MIT differential equation---9,10
- 黑马程序员--集合
- C语言学习笔记9--结构体
- 寻找大学目标及行动步骤——记ITAEM团队第二期宣讲会(2014.05.14)
- js的编码成gb2312的编码函数(URLEncode)
- vfnjh
- 豆瓣图书查询升级版“扫扫图书”
- cdvgfx