
effective c++
文章平均质量分 74
effective c++
却道天凉_好个秋
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
Effective C++条款55:杂项讨论——让自己熟悉Boost
一、Boost包含的内容Boost的内容很多,下面只列出了部分二、总结Boost是一个社群,也是一个网站。致力于免费、源码开放、同僚复查的C++程序库开发。Boost在C++标准化过程中扮演深具影响力的角色 Boost提供许多TR1组件实现品,以及其他许多程序库...转载 2021-02-19 09:32:19 · 165 阅读 · 0 评论 -
Effective C++条款54:杂项讨论——让自己熟悉包括TR1在内的标准程序库
一、C++标准的历史C++标准初始于1989年,由国际标准化组织(ISO)推动。ISO其实是一个大群国家标准组织,成员机构包括美国的ANSI 下面是C++标准的发展历程: ①C++98:于1998年批准,是第一份C++标准规则 官方名称是Inforamtion Trchnology-Programming Languages-C++,文档编号ISO/IEC 14882:1998 ②C++03:这是个所谓“技术勘误”(technical corrigendum,TC),内含不甚严重的C+转载 2021-02-19 09:31:14 · 212 阅读 · 1 评论 -
Effective C++条款53:杂项讨论——不要轻忽编译器的警告
一、忽略编译器的警告是一个不好的行为许多程序员习惯性的忽略编译器的警告,他们认为,如果问题很严重,编译器应该报出一个错误而非警告,于是他们习惯性的忽略了编译器的警告 这是不正确的行为二、来看一个案例现在我们有下面的继承体系:class B{public: virtual void f()const;};class D :public B{public: virtual void f();};其中可能会导致程序不明确的地方在: f()函转载 2021-02-19 09:27:50 · 283 阅读 · 0 评论 -
Effective C++条款52:定制new和delete——写了placement new也要写placement delete
placement new和placement delete在C++中可能并不常用,但是你需要了解它们 关于placement new语法可以参阅:https://blog.csdn.net/qq_41453285/article/details/104690501一、正常签名式的new和delete对于使用new来创建对象时,其可能在两个地方会抛出异常: ①当在调用new()时,new()函数中可能会抛出异常 ②如果new()函数没有抛出异常,但是后面对象的构造函数可能会抛出异常 当转载 2021-02-19 09:15:53 · 216 阅读 · 1 评论 -
Effective C++条款51:定制new和delete——编写new和delete时需固守常规
条款50介绍了为何要重载operator new和operator delete,本条款用来讲述重载operator new和operator delete时所要遵守的规则一、operator new所要遵守的规则operator new的一般规则为: 必须拥有正确的返回值:如果申请成功就返回指针指向于那块内存。如果不足就抛出bad_alloc异常(未设置new-handler的情况下) 内存不足时调用new-handling函数(见条款49):operator new实际上不只一次尝试分配内转载 2021-02-19 09:09:19 · 238 阅读 · 0 评论 -
Effective C++条款50:定制new和delete——了解new和delete的合理替换时机
一、重载operator new和operator delete的理由我们可以重载编译器的operator new和operator delete,下面给出了三个理由①用来检测运用上的错误下面是一些常见错误: new分配内存,但是没有delete掉,导致内存泄漏 对new所分配的内存,进行多次delete那么会导致不明确的行为 上面这些错误都是可以检测出来的 还有一种错误情况: 一些程序操作数据可能会导致数据“overruns”(写入点在分配内存尾端之后)或“underrun转载 2021-02-18 16:56:32 · 211 阅读 · 1 评论 -
Effective C++条款49:定制new和delete——了解new-handler的行为
一、set_new_handler()函数set_new_handler()函数语法介绍,参阅:https://blog.csdn.net/qq_41453285/article/details/103553037 当opertor new分配内存时: 旧C++标准中,让operator new返回null 现代C++标准中,operator new抛出异常(bad_alloc),并且该异常不能被operator new捕获,因此会被传播到内存索求处 我们可以在使用operator new转载 2021-02-18 16:48:09 · 172 阅读 · 0 评论 -
Effective C++条款48:模板与泛型编程——认识template元编程
待续。。。原创 2021-02-17 23:32:53 · 162 阅读 · 0 评论 -
Effective C++条款47:模板与泛型编程——请使用traits classes表现类型信息
一、traits机制 Traits机制可以参阅:https://blog.csdn.net/qq_41453285/article/details/103540156 以迭代器为演示案例标准库有一个advance()算法,该算法用来将迭代器移动给定距离,其第一个参数为迭代器,第二个参数为要移动的距离 我们知道迭代器分为5种: Input Iterator:这种迭代器所指的对象,不允许外界改变。只读 Output Iterator:只写 Forward Iterator:允许“写入转载 2021-02-17 23:31:51 · 113 阅读 · 0 评论 -
Effective C++条款46:模板与泛型编程——需要类型转换时请为模板定义非成员函数
一、非成员函数模板出错的例子 我们在条款24说过,对于Rational类来说,为了让所有的乘法操作都能通过操作,我们将operator*()函数定义为非成员函数版本(详情可以回过头再去看)。但是对于模板来说,这些规则可能不成立 例如下面我们把Rational和operator*()函数都定义为模板,代码如下://下面与条款24都相同,只是改为了模板template<typename T>class Rational {public: Rational(con转载 2021-02-16 22:03:22 · 214 阅读 · 1 评论 -
Effective C++条款45:模板与泛型编程——运用成员函数模板接受所有兼容类型
一、添加成员函数模板以一个例子引出,何时设计成员函数模板第一步:我们知道指针的一个特点就是:支持隐式转换。例如“指向non-const对象的指针可以转换为指向const对象”,“派生类指针可以隐式转换为基类指针”等等。代码如下:class Top {};class Middle :public Top {};class Bottom :public Middle {};Top* pt1 = new Middle; //将Miffle*转换为Top*Top* pt2 = new转载 2021-02-16 18:28:24 · 237 阅读 · 1 评论 -
Effective C++条款44:模板与泛型编程——将与参数无关的代码抽离templates
一、代码重复与对应策略对于函数而言假设我们编写某些函数(不止一个),这些函数当有有部分代码都是相同的,因此我们认为这份代码对于程序来说是重复的 那么此时我可以将这些函数共同的部分抽取出来,然后放在另一个函数中,让原本那些函数调用这个新函数。这样就达到了缩减代码的效果对于类而言假设我们在编写一组类,而这些类中有些部分都是相同的,因此我们认为这份代码对于程序来说是重复的 那么此时我们可以将这些类中共同的部分抽取出来,建立一个新类,然后让原本那些类继承于这个新类。这样就达到了缩减代码的效转载 2021-02-15 09:23:42 · 217 阅读 · 1 评论 -
Effective C++条款43:模板与泛型编程——学习处理模板化基类内的名称
一、模板中,派生类不可调用模板基类的成员函数在模板类中,如果一个派生类在其方法中调用了基类的方法,那么这段代码可能无法编译通过 备注(重点): 这一现象是与编译器有关的,Effective C++的作者编译的时候出错 本人使用VS编译的时候没有出错 因此这个问题是与编译器有关 演示说明假设现在有这样一个类体系: 我们有若干公司类,其包含两个成员函数可以用来将信息发送到公司(一个为发送加密信息,一个为发送不加密信息) 有一个MsgSender类,其中有两个成员函数,函数中可以转载 2021-02-14 17:23:12 · 144 阅读 · 1 评论 -
Effective C++条款42:模板与泛型编程——了解typename的双重意义
一、意义①意义①:typename可以在template中声明类型参数 在template中声明类型参数时,typename和class是等价的,两者都可以 例如://两者是等价的template<class T> class Widget;template<typename T> class Widget;二、意义②意义②:可以用来声明某种类型演示说明现在我们有一个模板,其接受一个STL容器类型,然后打印容器中的第二个元素的值,但是这个模板可能会转载 2021-02-14 09:52:48 · 210 阅读 · 1 评论 -
Effective C++条款41:模板与泛型编程——了解隐式接口和编译期多态
一、面向对象编程中提供的是“显式接口”和“运行期多态”概述:面向对象编程世界总是以“显式接口”和“运行期多态”解决问题演示说明下面定义一个类,用作演示:class Widget {public: Widget(); virtual ~Widget(); virtual std::size_t size()const; virtual void normalize(); void swap(Widget& other);转载 2021-02-13 21:04:42 · 186 阅读 · 1 评论 -
Effective C++条款40:继承与面向对象——明智而审慎地使用多重继承
一、多重继承中,接口调用的歧义性当一个类继承自两个基类时,两个基类包含有相同的名称(如函数、typedef等),那么调用时就会产生歧义性演示案例class BorrowableItem {public: void checkOut();};class ElectronicGadget {private: bool checkOut()const; //注意,此处的为private};//多重继承class MP3Player :public转载 2021-02-13 10:28:44 · 217 阅读 · 0 评论 -
Effective C++条款39:继承与面向对象——明智而审慎地使用private继承
一、先介绍一下private继承的语法某派生类private继承于基类之后: ①基类中的所有内容(不论是public、protected、private)在派生类中都是不可访问的 ②不能再将派生类对象转换为基类对象 ③派生类仍然可以重写/隐藏基类的成员方法 二、private继承意味着什么关系?private继承意为implemented-terms-of(根据某物实现出): 假设你让class D以private继承于class B,用意为采用class B内的某些特性来实现cl转载 2021-02-13 10:05:59 · 273 阅读 · 0 评论 -
Effective C++条款38:继承与面向对象——通过复合塑模出has-a或“根据某物实现出”
一、类的复合关系复合:是类型之间的一种关系,是指在某种类型的对象内包含其他类型的对象 复合(composition)还有一些其他的同义词,例如layering(分层),containment(内含),aggregation(聚合)、embedding(内嵌) 例如:class Address {};class PhoneNumber {};//此类为复合类型class Person{public: //...private: std::string转载 2021-02-13 09:54:07 · 178 阅读 · 0 评论 -
Effective C++条款37:继承与面向对象——绝不重新定义继承而来的缺省参数值
前言在条款36介绍过,在继承体系中,派生类最好只重写覆盖virtual函数,而不要去隐藏基类的non-virtual函数 因此,本条款要介绍的“不要重新定义继承而来的缺省参数值”,是针对于virtual函数而言的 一个重要的概念:virtual函数是动态绑定的,而virtual函数的缺省参数值却是静态绑定的一、静态类型、动态类型静态类型:在被声明时所采用的的类型 动态类型:目前所知对象的类型演示案例下面是一个继承体系class Shape {public: enum转载 2021-02-12 10:24:27 · 155 阅读 · 0 评论 -
Effective C++条款36:继承与面向对象——绝不重新定义继承而来的non-virtual函数
一、看一个隐藏non-virtual函数的例子假设class D以public的方式继承于class B,代码如下:class B {public: void mf();};class D :public B {};int main(){ D x; B *pB = &x; pB->mf(); //调用B::mf() D *pD = &x; pD->mf(); //调用D::mf() r转载 2021-02-11 15:23:50 · 143 阅读 · 0 评论 -
Effective C++条款35:继承与面向对象——考虑virtual函数以外的其他选择
假设现在有这样的一个程序: 正在写一个视频游戏软件,现在为游戏内的任务设计一个继承体系 现在我们定义一个函数healthValue(),用来表示人物的健康状态,其返回一个整数 由于不同的人可能会以不同的方式计算他们的健康指数,因此我们可能会想到将healthValue()函数定义为virtual。如下所示 class GameCharacter {public: //返回人物的健康指数,派生类可以重新定义它 virtual int healthValue() cons转载 2021-02-11 14:50:56 · 191 阅读 · 1 评论 -
Effective C++条款34:继承与面向对象——区分接口继承和实现继承
一、继承中接口的处理方式作为类的设计者,对于基类的成员函数可以大致做下面三种方式的处理: ①纯虚函数:基类定义一个纯虚函数,然后让派生类去实现 ②非纯虚的virtual虚函数:基类定义一个非纯虚的virtual虚函数,然后让派生类去重写覆盖(override) ③普通的成员函数:基类定义一个普通的成员函数,并且不希望派生类去隐藏 本文依次介绍上面这三种设计的原理。下面定义一个类,作为本文讲解的基础:class Shape {public: virtual void d转载 2021-02-10 17:03:27 · 150 阅读 · 0 评论 -
Effective C++条款33:继承与面向对象——避免遮掩继承而来的名字
一、变量隐藏使用规则当全局和局部存在相同的变量时,在局部作用域中,全局作用域的变量名会被隐藏,优先使用局部的变量 例如:int x; //全局变量void someFunc(){ double x; //局部变量 std::cin >> x; //局部变量赋值]二、继承中的隐藏与重写(覆盖)当基类中定义的变量/成员函数,派生类也定义同名的时,基类的变量/成员函数就会在派生类中被隐藏演示案例class Base{privat转载 2021-02-09 20:00:53 · 116 阅读 · 0 评论 -
Effective C++条款32:继承与面向对象——确定你的public继承塑模出is-a关系
一、“is-a”的概念以C++进行面向对象编程,最重要的一个规则是:public inheritance(公开继承)意味“is-a”(是一种)的关系 如果你令class D以public形式继承class B,你便是告诉编译器: 每一个类型为D的对象同时也是一个类型为B的对象。反之不是 B对象可使用的地方,D对象一样可以使用。反之不是 演示案例下面Student类public继承于Personclass Person {};class Student :public Perso转载 2021-02-09 17:00:35 · 226 阅读 · 0 评论 -
Effective C++条款31:实现——将文件间的编译依存关系降至最低
待续。。。原创 2021-02-08 19:34:04 · 119 阅读 · 0 评论 -
Effective C++条款30:实现——透彻了解inlining的里里外外
一、inline的优缺点优点免除函数调用成本缺点以函数本体代替函数调用,因此目标码增大 在一台内存优先的机器上,过度使用inline会造成程序体积太大 即使拥有虚内存,inline造成的代码膨胀也会造成额外的换页行为,降低指令高速缓存装置的集中率,以及伴随效率的损失二、隐式内联、显式内联inline只是对编译器的一个申请,不是强制命令 隐式内联:当成员函数定义在类的内部时,这个函数是隐式inline的(隐式内联只有这一种情况)。例如:class Person {转载 2021-02-08 14:19:32 · 257 阅读 · 0 评论 -
Effective C++条款29:实现——为“异常安全”而努力是值得的
一、可能抛出异常的演示案例下面是一个class,用来表现夹带背景图片的GUI菜单,其中有个互斥器作为并发控制:void lock(Mutex* pm); //锁定pm所指的互斥器void unlock(Mutex* pm); //将互斥器解锁class PrettyMenu {public: void changeBackground(std::istream& imgSrc) { lock(&mutex); //取得互斥器转载 2021-02-08 14:02:36 · 225 阅读 · 0 评论 -
Effective C++条款28:实现——避免返回handles指向对象内部成分
一、概述演示案例下面是一些关于图形的类 Point是用来表示坐标中的点;RectData代表矩形的左上角与右上角;Rectangle用来管理矩形,其中有一个RectData成员变量class Point { //点public: Point(int x, int y); void setX(int newVal); void setY(int newVal);};struct RectData { //矩形左上角与右上角 Point ul转载 2021-02-07 23:04:26 · 254 阅读 · 0 评论 -
Effective C++条款27:实现——尽量少做转型动作
一、数据类型转换语法C语言风格的类型转换格式C++新式转型const_cast、dynamic_cast、reinterpret_cast、static_cast 详细介绍参阅:https://blog.csdn.net/qq_41453285/article/details/89187875二、建议使用C++新式转型旧式转型虽然虽然合法,但是程序设计时应该尽量使用新式转型。原因如下: ①新式转型在代码中很容易被识别出来 ②新式转型使转型动作的目标比较有限。例如你打转载 2021-02-06 20:42:29 · 118 阅读 · 0 评论 -
Effective C++条款26:实现——尽可能延后变量定义式的出现时间
一、变量定义的成本只要你定义一个变量,该变量带有构造函数与析构函数,那么: 当你定义这个变量时就要执行它的构造函数 变量生命周期结束后就要执行他的析构函数 二、尽量延迟变量定义的时间变量定义需要执行构造与析构函数,因此在某些情况下为了提高程序的效率,应该延迟变量定义的时间。请看下面的演示案例:演示案例下面定义一个函数,用来对密码进行加密,如果参数传入的密码过段就抛出一个logic_error异常(见条款54)//参数:要加密的密码//返回值:加密后的密码std::st转载 2021-02-06 20:02:47 · 251 阅读 · 0 评论 -
Effective C++条款25:设计与声明——考虑写出一个不抛异常的swap函数
一、标准模板库中的swap函数标准模板库中的swap函数,其是STL中的一部分,后来成为异常安全性编程(见条款29)以及用来处理自我赋值可能性(见条款11)的一个常见机制 下面是STL中swap的源码:只要类型T支持拷贝(拷贝构造函数或者拷贝赋值运算符),缺省的swap函数就可能帮你对两个类型为T的对象进行兑换为什么不使用std::swap()函数: 从源码可以看出,std::swap函数,其涉及三个对象的复制操作:a复制到temp,b复制到a,temp复制到b 但是对于我们自己设计的类转载 2021-02-06 17:42:40 · 260 阅读 · 0 评论 -
Effective C++条款24:设计与声明之——若所有参数皆需类型转换,请为此采用non-member函数
一、看一个类型转换的错误案例现在我们有一个类,来用表现出有理数,允许整数“隐式转换”为有理数 class Rational { public: //构造函数未设置为explicit,因为我们希望一个int可以隐式转换为Rational Rational(int numerator = 0, int denominator = 1); int numerator()const; int denominator()const; .转载 2021-02-06 10:11:57 · 150 阅读 · 0 评论 -
Effective C++ 条款23:设计与声明——宁以 non-member、non-friend 替换 member 函数
想象有个 class 用来表示网页浏览器。这样的 class 可能提供的众多函数中,有一些用来清除下载元素高速缓存区(cache of download elements)、清除访问过的 URLs 的历史记录(history of visited URLs)、以及移除系统中的所有cookies,如下所示:class WebBrowser{public: ... void clearCache(); void clearHistory(); void removeCookies(); ...转载 2021-02-04 23:18:17 · 162 阅读 · 0 评论 -
Effective C++条款22:设计与声明——将成员变量声明为private
一、不要把成员变量声明为public统一性如果成员变量不是public,那么客户端只能通过函数来对成员变量进行操作 通过函数来操作类这也是一个标准,很多面向对象语言都是这么设计的 class AccessLevels { public: int getReadOnly()const { return readOnly; } void setReadWrite(int value) { readWrite = value; } int.转载 2021-02-04 22:57:13 · 213 阅读 · 0 评论 -
Effective C++条款21:设计与声明——必须返回对象时,别妄想返回其reference
前面一篇文章我们介绍了,向函数中传递对象时,应以const引用的方式传递它,但是并不是在任何情况下使用引用都是正确的,文本来介绍一些情况一、演示说明现在我们有一个用来变现有理数的class,内含一个函数用来计算两个有理数的乘积 下面代码中的operator*是正确的,也是合理的 class Rational { public: Rational(int numerator = 0, int denominator = 1); private: .转载 2021-02-03 23:33:05 · 187 阅读 · 0 评论 -
Effective C++条款20:设计与声明——宁以pass-by-reference-to-const替换pass-by-value
一、传值调用会造成代码执行效率低 传值调用为什么会造成代码执行效率低?因为传值调用的时候,是传递对象的一个副本,因此是调用对象的拷贝构造函数将对象复制一份,然后传递给函数。效率比较低 下面来看一个例子:有一个基类(Person)与一个派生类(Student),并且定义一个函数(validateStudent),参数接受一个Student对象(传值调用) class Person { public: Person(); virtual ~Per.转载 2021-02-03 22:55:33 · 153 阅读 · 0 评论 -
Effective C++条款19:设计与声明——设计class犹如设计type
C++就像在其他OOP(面向对象编程)语言一样,当你定义一个新class,也就定义了一个新type。身为C++程序员,你的许多时间主要用来扩张你的类型系统。这意味着你并不只是class设计者,还是type设计者。重载函数和操作符、控制内存的分配和归还、定义对象的初始化和终结......全部都在你手上。因此你应该带着和“语言设计者当初设计语言内置类型时”一样的谨慎来研讨class的设计。 设计优秀的classes是一项艰巨的工作,因为设计好的types是一项艰巨的工作,好的types有自然的语法,直观的语义原创 2021-02-02 23:23:34 · 107 阅读 · 0 评论 -
Effective C++条款18:设计与声明——让接口容易被正确使用,不易被误用
总结:1)好的接口很容易被正确使用,不容易被误用。你应该在你的是所有接口中努力达成这些性质;2)“促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容;3)“阻止误用”的办法包括建立新类型、限制类型上的操作,束缚对象值,以及消除客户的资源管理责任;4)tr1::shared_ptr支持定制型删除器(custom deletor)。这可防范dll的问题,可被用来自动解除互斥锁(mutex:见条款14);...原创 2021-02-02 23:14:27 · 125 阅读 · 0 评论 -
Effective C++条款17:以独立语句将newed对象置入智能指针
一、演示案例现在我们有个函数返回处理程序的优先权,然后用另一个函数在某动态分配所得的Widget上进行某些带有优先权的处理 //返回优先权 int priority(); //根据优先权处理对象 void processWidget(std::tr1::shared_ptr<Widget> pw, int priority); 如果我们使用下面的方法调用函数是错误的:因为processWidget参数1需要传入一个shared_ptr类型..转载 2021-02-01 22:59:18 · 188 阅读 · 0 评论 -
Effective C++条款16:成对使用new和delete时要采取相同形式
一、概念如果申请(new)的对象为单一对象,那么在释放(delete)的时候就只要简单的释放即可 如果申请(new [])的对象为对象数组,那么在释放(delete [])的时候就要以[]释放之二、演示案例申请单一对象: std::string* stringArray = new std::string; delete stringArray; //正确的 //delete[] stringArray;错误的 申请对象数组: std...转载 2021-02-01 22:48:41 · 145 阅读 · 0 评论