1. private 继承介绍 Item 32表明C++把public继承当作”is-a”关系来对待.考虑一个继承体系,一个类Student public 继承自类Person,如果一个函数的成功调用需要从Student到Person的隐式转换,这时候“is-a”关系就出现了.对于一部分实例,使用private继承来代替public继承也是有价值的事情: class Person { ... }; class Student: private Person { ... }; // inherit…
1. 多继承的两个阵营 当我们谈论到多继承(MI)的时候,C++委员会被分为两个基本阵营.一个阵营相信如果单继承是好的C++性质,那么多继承肯定会更好.另外一个阵营则争辩道单继承诚然是好的,但多继承太麻烦,而不值得去使用它.在这个条款中,我的主要目标是让你明白多继承的这两个观点. 2. 从多个基类中继承的名字不能相同 第一件事情是你需要认识到使用MI进行设计时,从多个基类中可能会继承相同的名字(例如函数或者typedef等等).这就会导致模棱两可的问题,例如: class BorrowableI…
我们首先看一下为什么数据成员不应该是public的,然后我们将会看到应用在public数据成员上的论证同样适用于protected成员.最后够得出结论:数据成员应该是private的. 1. 为什么数据成员不能是public的? 为什么数据成员不能够是public的? 2.1 一致性 让我们从句法的一致性开始(Item 18).如果数据成员不是Public的,那么客户访问对象的唯一方法就是通过成员函数.如果所有的公共接口都是函数,客户就不必记住访问一个类的成员时是否使用括号了.这方便了客户的使用…
1. C++0x的历史渊源 C++标准——也就是定义语言的文档和程序库——在1998被批准.在2003年,一个小的“修复bug”版本被发布.然而标准委员会仍然在继续他们的工作,一个“2.0版本”的C++标准预计在2009年被发布(虽然所有的工作很有可能在2007年底被完成).直到现在,发布下一版C++的预计年份还没有被确定,这就解释了为什么人们把下一版C++叫做“C++0x”——C++的200x年版本. C++0x可能会包含一些有趣的新的语言特性,但是大多数新C++功能将会以标准库附加物的形式被…
1. 何为public继承的”is-a”关系 在C++面向对象准则中最重要的准则是:public继承意味着“is-a”.记住这个准则. 如果你实现一个类D(derived)public继承自类B(base),你在告诉c++编译器(也在告诉代码阅读者),每个类型D的对象也是一个类型B的对象,反过来说是不对的.你正在诉说B比D表示了一个更为一般的概念,而D比B表现了一个更为特殊的概念.你在主张:任何可以使用类型B的地方,也能使用类型D,因为每个类型D的对象都是类型B的对象:反过来却不对,也就是可以使…
1. 使用模板可能导致代码膨胀 使用模板是节省时间和避免代码重用的很好的方法.你不需要手动输入20个相同的类名,每个类有15个成员函数,相反,你只需要输入一个类模板,然后让编译器来为你实例化20个特定的类和300个你需要的函数.(只有在被使用的情况下类模版的成员函数才会被隐式的实例化,所以只有在300个函数被实际用到的情况下才会生成300个成员函数.)函数模板同样吸引人.你不用手动实现许多函数,你只需要实现一个函数模板,然后让编译器来做余下的事情. 然而在有些时候,如果你不小心,使用模板会导致代…
Item 50中解释了在什么情况下你可能想实现自己版本的operator new和operator delete,但是没有解释当你实现的时候需要遵守的约定.遵守这些规则并不是很困难,但是它们其中有一些并不直观,所以知道这些规则是什么很重要. 1. 定义operator new的约定 1.1 约定列举 我们以operator new开始.实现一个一致的operator new需要有正确的返回值,在没有足够内存的时候调用new-handling函数(见Item 49),并且做好准备处理没有内存可分配…
1. 普通作用域中的隐藏 名字实际上和继承没有关系.有关系的是作用域.我们都知道像下面的代码: int x; // global variable void someFunc() { double x; // local variable std::cin >> x; // read a new value for local x } 读入x的声明指向的是本地的x而不是全局的x,因为内部作用域的名字将外部作用域的变量隐藏掉了.我们将作用域的这种情况用以下方式进行可视化: 当编译器在someFu…
1. 问题的引入——派生类不会发现模板基类中的名字 假设我们需要写一个应用,使用它可以为不同的公司发送消息.消息可以以加密或者明文(未加密)的方式被发送.如果在编译阶段我们有足够的信息来确定哪个信息会被发送到哪个公司,我们可以使用基于模板的解决方案: class CompanyA { public: ... void sendCleartext(const std::string& msg); void sendEncrypted(const std::string& msg); ...…
1. 什么样的接口才是好的接口 C++中充斥着接口:函数接口,类接口,模板接口.每个接口都是客户同你的代码进行交互的一种方法.假设你正在面对的是一些“讲道理”的人员,这些客户尝试把工作做好,他们希望能够正确使用你的接口.在这种情况下,如果接口被误用,你的接口应该至少负一部分的责任.理想情况下,如果使用一个接口没有做到客户希望做到的,代码应该不能通过编译:如果代码通过了编译,那么它就能做到客户想要的. 2. 编写好的接口的方法列举 2.1 使接口不容易被误用——通过引入新的类型 开发出容易被正确使…