随笔分类 - Effective c++
摘要:1. 为什么不要重新定义继承而来的非虚函数——实际论证 假设我告诉你一个类D public继承类B,在类B中定义了一个public成员函数mf。Mf的参数和返回类型并不重要,所以假设它们都是void。实现如下: 我们不需要了解B,D或者mf的任何细节,考虑一个类型D的对象x, 你会感到很吃惊,如果下
阅读全文
摘要:1. 突破思维——不要将思维限定在面向对象方法上 你正在制作一个视频游戏,你正在为游戏中的人物设计一个类继承体系。你的游戏处在农耕时代,人类很容易受伤或者说健康度降低。因此你决定为其提供一个成员函数,healthValue,返回一个整型值来表明一个人物的健康度。因为不同的人物会用不同的方式来计算健康
阅读全文
摘要:看上去最为简单的(public)继承的概念由两个单独部分组成:函数接口的继承和函数模板继承。这两种继承之间的区别同本书介绍部分讨论的函数声明和函数定义之间的区别完全对应。 1. 类函数的三种实现 作为一个类设计者,有时候你只想派生类继承成员函数的接口(声明)。有时候你想让派生类同时继承接口和实现,但
阅读全文
摘要:1. 普通作用域中的隐藏 名字实际上和继承没有关系。有关系的是作用域。我们都知道像下面的代码: 读入x的声明指向的是本地的x而不是全局的x,因为内部作用域的名字将外部作用域的变量隐藏掉了。我们将作用域的这种情况用以下方式进行可视化: 当编译器在someFunc的作用域中时,遇到了名字x,它们先在本地
阅读全文
摘要:1. 何为public继承的”is-a”关系 在C++面向对象准则中最重要的准则是:public继承意味着“is-a”。记住这个准则。 如果你实现一个类D(derived)public继承自类B(base),你在告诉c++编译器(也在告诉代码阅读者),每个类型D的对象也是一个类型B的对象,反过来说是
阅读全文
摘要:1. 牵一发而动全身 现在开始进入你的C++程序,你对你的类实现做了一个很小的改动。注意,不是接口,只是实现,而且是private部分。然后你需要rebuild你的程序,计算着这个build应该几秒钟就足够了。毕竟,只修改了一个类。你点击了build 或者输入了make( 或者其他方式),你被惊到了
阅读全文
摘要:最近北京房价蹭蹭猛涨,买了房子的人心花怒放,没买的人心惊肉跳,咬牙切齿,楼主作为北漂无房一族,着实又亚历山大了一把,这些天晚上睡觉总是很难入睡,即使入睡,也是浮梦连篇,即使亚历山大,对C++的热情和追求还是不减,应该是感动了周公吧,梦境从此处开始,大师入场来给我安慰了。。。 11点躺在床上了,脑子里
阅读全文
摘要:异常安全在某种意义上来说就像怀孕。。。但是稍微想一想。在没有求婚之前我们不能真正的讨论生殖问题。 假设我们有一个表示GUI菜单的类,这个GUI菜单有背景图片。这个类将被使用在多线程环境中,所以需要mutex进行并发控制。 我们看一种PrettyMenu的changeBackground函数的可能实现
阅读全文
摘要:假设你正在操作一个Rectangle类。每个矩形可以通过左上角的点和右下角的点来表示。为了保证一个Rectangle对象尽可能小,你可能决定不把定义矩形范围的点存储在Rectangle类中,而是把它放入一个辅助结构体中,Rectangle中声明一个指向它的指针就可以了: 1. 由返回指向对象内部数据
阅读全文
摘要:C++设计的规则是用来保证使类型相关的错误不再可能出现。理论上来说,如果你的程序能够很干净的通过编译,它就不会尝试在任何对象上执行任何不安全或无意义的操作。这个保证很有价值,不要轻易放弃它。 不幸的是,casts颠覆了类型系统。它导致了各种麻烦的出现,一些很容易识别,一些却很狡猾(不容易被识别)。如
阅读全文
摘要:1. 定义变量会引发构造和析构开销 每当你定义一种类型的变量时:当控制流到达变量的定义点时,你引入了调用构造函数的开销,当离开变量的作用域之后,你引入了调用析构函数的开销。对未使用到的变量同样会产生开销,因此对这种定义要尽可能的避免。 2. 普通函数中的变量定义推迟 2.1 变量有可能不会被使用到的
阅读全文
摘要:1. swap如此重要 Swap是一个非常有趣的函数,最初作为STL的一部分来介绍,它已然变成了异常安全编程的中流砥柱(Item 29),也是在拷贝中应对自我赋值的一种普通机制(Item 11)。Swap非常有用,恰当的实现swap是非常重要的,与重要性伴随而来的是一些并发症。在这个条款中,我们将探
阅读全文
摘要:1. 将需要隐式类型转换的函数声明为成员函数会出现问题 使类支持隐式转换是一个坏的想法。当然也有例外的情况,最常见的一个例子就是数值类型。举个例子,如果你设计一个表示有理数的类,允许从整型到有理数的隐式转换应该是合理的。在C++内建类型中,从int转换到double也是再合理不过的了(比从doubl
阅读全文
摘要:1. 非成员非友元好还是成员函数好? 想象一个表示web浏览器的类。这样一个类提供了清除下载缓存,清除URL访问历史,从系统中移除所有cookies等接口: 许多用户想将这些动作一块执行,所以web浏览器为此可以提供一个函数: 当然,这个功能也可以通过非成员函数来提供,让它调用合适的成员函数就可以了
阅读全文
摘要:我们首先看一下为什么数据成员不应该是public的,然后我们将会看到应用在public数据成员上的论证同样适用于protected成员。最后够得出结论:数据成员应该是private的。 1. 为什么数据成员不能是public的? 为什么数据成员不能够是public的? 2.1 一致性 让我们从句法的
阅读全文
摘要:1. 问题的提出:要求函数返回对象时,可以返回引用么? 一旦程序员理解了按值传递有可能存在效率问题之后(Item 20),许多人都成了十字军战士,决心清除所有隐藏的按值传递所引起的开销。对纯净的按引用传递(不需要额外的构造或者析构)的追求丝毫没有懈怠,但他们的始终如一会产生致命的错误:它们开始传递指
阅读全文
摘要:1. 按值传递参数会有效率问题 默认情况下,C++向函数传入或者从函数传出对象都是按值传递(pass by value)(从C继承过来的典型特性)。除非你指定其他方式,函数参数会用实际参数值的拷贝进行初始化,函数调用者会获得函数返回值的一份拷贝。这些拷贝由对象的拷贝构造函数生成。这使得按值传递(pa
阅读全文
摘要:1. 你需要重视类的设计 c++同其他面向对象编程语言一样,定义了一个新的类就相当于定义了一个新的类型(type),因此作为一个c++开发人员,大量时间会被花费在扩张你的类型系统上面。这意味着你不仅仅是一个类的设计者同时是一个类型设计者。重载函数和运算符,控制内存分配和释放,定义对象初始化和终结,这
阅读全文
摘要:1. 什么样的接口才是好的接口 C++中充斥着接口:函数接口,类接口,模板接口。每个接口都是客户同你的代码进行交互的一种方法。假设你正在面对的是一些“讲道理”的人员,这些客户尝试把工作做好,他们希望能够正确使用你的接口。在这种情况下,如果接口被误用,你的接口应该至少负一部分的责任。理想情况下,如果使
阅读全文
摘要:1. 可能会出现资源泄漏的一种用法 假设我们有一个获取进程优先权的函数,还有一个在动态分配的Widget对象上根据进程优先权进行一些操作的函数: 注意这里使用了对象管理资源的用法(Item 13),processWidget为它需要处理的动态分配对象Widget使用了智能指针(tr1::shared
阅读全文