![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Effective C++
IT呵呵哒
这个作者很懒,什么都没留下…
展开
-
条款04:确定对象被使用之前先被初始化
读取未初始化的值会导致不明确的行为。 在C++中,规则很简单:确保每一个构造函数都将对象的每一个成员初始化。class PhoneNumber{...};class ABEntry{ //ABEntry = "Address Book Entry"public: ABEntry(const std::string& name...原创 2019-02-27 22:56:37 · 120 阅读 · 0 评论 -
条款19: 设计class犹如设计type
C++就像在其他OOP(面向对象编程)语言一样,当你定义一个新class,也就定义了一个新type。身为C++程序员,你的许多时间主要用来扩张你的类型系统。这意味着你并不只是class设计者,还是type设计者。重载函数和操作符、控制内存的分配和归还、定义对象的初始化和终结......全部都在你手上。因此你应该带着和“语言设计者当初设计语言内置类型时”一样的谨慎来研讨class的设计。...原创 2019-05-28 22:02:07 · 243 阅读 · 0 评论 -
条款18:让接口容易被正确使用,不易被误用
欲开发一个“容易被正确使用,不容易被误用”的接口,首先必须考虑使用者可能做出什么样的错误。假设你为一个用来表现日期的class设计构造函数:class Data{public: Date(int month, int day, int year); ...}; 乍见之下这个接口通情达理。但是它的使用者很容易犯下至少两个错误。第一,他们也许会以错误的次序传递参...原创 2019-04-14 22:34:25 · 247 阅读 · 0 评论 -
条款17:以独立语句将newed对象置入智能指针
假设我们有个函数用来揭示处理程序的优先权,另一个函数用来动态分配所得的Widget上进行某些带有优先权的处理:int priority();void processWidget(std::tr1::shared_ptr<Widget> pw, int priority); 现在考虑调用processWidget:processWidget(new Widget,...原创 2019-04-12 19:55:40 · 145 阅读 · 0 评论 -
条款15:在资源管理类中提供原始资源的访问
当你使用智能如auto_ptr或std::tr1::share_ptr保存一个factory函数如createInvestment的调用结果时:std::tr1::shared_ptr<Investment> pInv(createInvestment()); 假设你希望以某个函数处理Investment对象,像这样:int daysHeld(const I...原创 2019-04-08 22:08:17 · 115 阅读 · 0 评论 -
条款14:在资源管理类中小心copying
假设我们使用C API函数处理类型为Mutex的互斥器对象,共有lock和unlock两函数可用:void lock(Mutex* pm); //锁定pm所指的对象void unlock(Mutex* pm); //将互斥器解除锁定 为确保绝不会忘记将一个被锁住的Mutex解锁,你可能...原创 2019-04-01 21:47:03 · 135 阅读 · 0 评论 -
条款16:成对使用new和delete时要采取相同形式
当你使用new(也就是通过new动态生成一个对象),有两件事发生。第一,内存被分配出来(通过名为 operator new的函数)。第二,针对此内存会有一个(或更多)构造函数被调用。当你使用delete,也有两件事发生:针对此内存会有一个(或多个)析构函数被调用,然后内存才被释放(通过名为 operator delete的函数)。delete的最大问题在于:即将被删除的内存之内究竟存有多少对象...原创 2019-04-10 20:47:04 · 126 阅读 · 0 评论 -
条款13:以对象管理资源
假设我们使用一个用来塑模投资行为的程序库,其中各式各样的投资类型继承自一个root class Investment:class Investment{...}; //"投资类型",继承体系中的root class 假设这个程序库通过一个工厂函数提供我们特定的Investment对象:Investment* createInvesment();...原创 2019-03-30 15:31:05 · 175 阅读 · 0 评论 -
条款12:复制对象时勿忘其每一个成分
设计良好之面向对象系统会将对象的内部封装起来,只留下两个函数负责对象拷贝(复制),那便是带着适切名称的copy构造函数和copy assignment操作符,称之为copying函数。 考虑一个class用来表现顾客,其中手工写出(而非编译器创建)copying函数,使得外界对它们的调用会被记录下来:void logCall(const std::string& funcN...原创 2019-03-22 22:09:15 · 125 阅读 · 0 评论 -
条款11:在operator=中处理“自我赋值”
“自我赋值”发生在对象被赋值给自己时: class Widget{...};Widget w;... w = w; //赋值给自己以上是比较明显的赋值,也有一些赋值动作不总是那么可被一眼辨识出来,例如:a[i] = a[j]; 如果i和j有相同的值,这便是是个自我赋值。*px = *py;如果px和p...原创 2019-03-18 22:03:25 · 153 阅读 · 0 评论 -
条款10:令operator=返回一个reference to *this
关于赋值,你可以把它们写成连锁形式:int x,y,z;x = y = z = 15; //赋值连锁形式 因为赋值采用右结合律,所以上述赋值被解析为:x = (y = (z = 15)); 为了实现“连锁赋值”,赋值操作符必须返回一个reference指向操作符左侧的实参。class Widget{public: ...原创 2019-03-17 22:24:32 · 241 阅读 · 0 评论 -
条款09:绝不在构造和析构过程中调用virtual函数
在C++中,不应该在构造函数和析构函数期间调用virtual函数。 这里有一个模拟股市交易的类:class Transaction{ //所有交易的base classpublic: Transaction(); virtual v...原创 2019-03-17 22:06:26 · 172 阅读 · 0 评论 -
条款08:别让异常逃离析构函数
C++并不禁止析构函数吐出异常,但它不鼓励你这样做。class Widget{public: ... ~Widget(){...} //假设这个可能吐出一个异常};void doSonmething(){ std::vector<Widget> v; ... //v在这里自动销毁...原创 2019-03-11 22:44:35 · 111 阅读 · 0 评论 -
条款06:若不想使用编译器自动生成的函数,就该明确拒绝
当你不想class支持某一特定机能,只要不声明对应的函数就是了。但是这个策略对copy构造函数和copy assignment操作符却不起作用,因为你不声明它们时,而某些尝试调用它们,编译器会自动生成。 所有编译器产出的函数都是public。为阻止这些函数被创建出来,你可以将copy构造函数或copy assignment操作符声明为private。阻止了编译器暗自创建其专属版本;而...原创 2019-03-04 21:04:58 · 142 阅读 · 0 评论 -
条款05:了解C++默默编写并调用哪些函数
什么时候empty class(空类)不再是个empty呢?当C++处理过它之后。如果你定义类的时候自己没有声明,编译器就会为它声明(编译器版本的)一个copy构造函数、一个copy assignment操作符和一个析构函数。如果你没有声明任何构造函数,编译器也会为你声明一个default构造函数。所有这些函数都是public并且inline。例:class Empty{};...原创 2019-03-04 20:36:46 · 86 阅读 · 0 评论 -
条款07:为多态基类声明virtual析构函数
有许多种做法可以记录时间,因此,设计一个TimeKeeper base class和一些derived classes作为不同的计时方法,相当合情合理:class TimerKeeper{public: TimeKeeper(); ~TimeKeeper(); ...};class AtomicClock:public TimeKeeper{...];...原创 2019-03-06 22:56:57 · 173 阅读 · 0 评论 -
条款03:尽可能使用const
const的一件奇妙的事情是,它允许你指定一个语义约束(也就是指定一个“不该被改动的对象”),而编译器会强制实施这项约束。它允许你告诉编译器某值应该保持不变。 char greeting[] = "hello"; char *testStr = "world"; char *p = greeting; //non-const pointer,non-const data co...原创 2019-02-26 22:39:12 · 98 阅读 · 0 评论 -
条款02:尽量以const,enum,inline替换 #define
条款核心:宁可以编译器替换预处理器。#define ASPECT _RATIO 1.653 ASPECT _RATIO也许从未被编译器看见,在预处理阶段它就被预处理器移走了,所以ASPECT_RATIO有可能没进入记号表。解决之道是以一个常量替换上述的宏(#define)const double AspectRatio = 1.653;因为预处理器阶段只是盲目的替换,可能...原创 2019-02-25 22:19:01 · 138 阅读 · 0 评论 -
条款20:宁以pass-by-reference-to-const替换pass-by-value
缺省情况下C++以by value方式(一个继承自c的方式)传递给对象至函数。除非你另外指定,否则函数都是以实际实参的复件为初值,而调用端获得的亦是函数返回值的一个复件。这些复件有对象的copy构造函数产出,这可能使得pass-by-value成为费时的操作。class Person{public: Person(); virtual ~Person(); .....原创 2019-06-04 21:45:16 · 170 阅读 · 0 评论