Effective C++
文章平均质量分 56
一千个读者就有一千个哈姆雷特,所以共同学习吧。还有很多不懂的地方,多多指教,欢迎指正,感谢!
慵懒小书虫
温故而知新,不会的地方太多了,所以要认真重新学起,以此记录下学习过程,加深印象。有的地方,自己不动手不知道错误在哪。如果能够对后来者有一丁点作用 那也是一件非常开心的事儿~
展开
-
Effective C++ 详解条款23:宁以non-member、non-friend替换member函数
总结:宁可拿non-member non-friend函数替换member 函数。这样做可以增加封装性、包裹弹性(packaging flexibility)和机能扩充性。举例:一个class用来表示网页浏览器。这样的class可能提供的众多函数中,有一些用来清除下载元素高速缓存区、清除访问过的URLS的历史记录、以及移除系统中的所有cookies:class webBrowser {public: ... void clearCache( ); void clearHisto原创 2021-05-18 22:23:03 · 567 阅读 · 1 评论 -
Effective C++ 详解条款22:将成员变量声明为private
假设有一个public成员变量,若最终取消了它。则所有使用它的客户码都会被破坏,而那是一-个不可知的大量。因此 public成员变量完全没有封装性。假设有一个protected成员变量,若最终取消了它,则所有使用它的derived classes都会被破坏,那往往也是个不可知的大量。因此,protected成员变量就像public成员变量一样缺乏封装性,因为在这两种情况下,如果成员变量被改变,都会有不可预知的大量代码受到破坏。一旦你将一个成员变量声明为public或protected而客户开始使用它,就原创 2021-05-18 20:47:08 · 450 阅读 · 1 评论 -
Effective C++ 详解条款21:必须返回对象时,别返回其reference
如果在stack空间创建一个local变量,并且你函数返回一个reference指向该local对象,将导致”无定义行为“,同样在,heap上也会导致operator*使用者不能获取到reference背后的指针而资源泄漏。//考虑一个用以表现有理数(rational numbers)的 class,内含一个函数用来计算两个有理数的乘积:class Rational {public: Rational (int numerator = 0,int denominator 1) ;原创 2021-05-17 19:51:18 · 396 阅读 · 1 评论 -
关于内联函数inline知识点
新的一周开始了!!还有一个月就要成为打工人,在这之前再多回顾多学习一些知识吧。ღ( ´・ᴗ・` )函数的引入可以减少程序的代码量,使得函数程序可以在代码间共享。但函数调用需要一些时空开销。在调用函数时,要先中断调用函数,将执行流程转移到被调函数中,待被调函数执行完毕后,返回调用函数。对于较长的函数,这种开销可以忽略不计。但对于很短的、调用频繁的函数体,这种开销不能忽略。例如void print(int x){ cout<<x<<endl;}使用函数可以提高程序原创 2021-05-17 10:34:03 · 318 阅读 · 0 评论 -
Effective C++ 详解条款20. 以pass-by-reference-to-const替换pass-by-value
缺省情况下C++以by value方式传递对象至函数,但pass by reference to const没有任何构造函数或析构函数被调用,因为没有任何新对象被创建,没有任何对象被调用,所有效率更高。以by reference方式传递参数也可以避免对象切割问题。当一个derived class对象以by value方式传递并被视为一个base class对象,base class的copy构造函数会被调用,而“造成此对象的行为像个derived class对象”的那些特化性质全被切割掉了,仅仅留下一个原创 2021-05-16 22:16:05 · 143 阅读 · 0 评论 -
码住!!!如何设计高效的classes——Effective C++ 详解条款19:设计class犹如设计type
Class 的设计就是type的设计。在定义一个新type 之前,请确定你已经考虑过本条款覆盖的所有讨论主题。因此,如何设计高效的classes,必须考虑以下问题:新type 的对象应该如何被创建和销毁?这会影响到你的class的构造函数和析构函数以及内存分配函数和释放函数的设计。(可参考第8章条款49-52)对象的初始化和对象的赋值该有什么样的差别?这决定你的构造函数和赋值操作符的行为以及其间的差距。别混淆了初始化和赋值,因为它们对应于不同的函数调用。(可参考条款4)新type原创 2021-05-11 21:54:36 · 149 阅读 · 0 评论 -
Effective C++ 详解条款18. 让接口容易被正确使用
例子1:导入简单的外覆类型假如有一个用来表现日期的class设计构造函数:class Date{public: Date(int month, int day, int year);}使用者很容易犯下两个错误:1.以错误的次序传递参数。2.传递一个无效的月份或天数。为了预防这样的问题,可以导入新的类型来获得预防,即导入外覆类型(wrapper types)来区别天数、月份和年份,然后于构造函数中使用这些类型:struct Day{ explicit Day(int d):val(d)原创 2021-05-09 22:31:25 · 275 阅读 · 0 评论 -
Effective C++ 详解条款17:以独立语句将newed对象置入智能指针
在语句内,编译器拥有自由度,容易泄露资源,processwidget (std::tr1::shared_ptr<Widget>(new widget), priority ()) ;在对processwidget的调用过程中可能引发资源泄漏,因为在“资源被创建(经由“new widget")”和“资源被转换为资源管理对象”两个时间点之间有可能发生异常干扰。解决办法:使用分离语句。(1)创建widge;(2)将它置入一个智能指针内,然后再把那个智能指针传给processwidget:原创 2021-05-07 11:33:50 · 174 阅读 · 2 评论 -
Effective C++ 详解条款16:成对使用new和delete时要采取相同形式
当你使用new(也就是通过new动态生成一个对象),有两件事发生:第一,内存被分配出来;第二,针对此内存会有一个(或更多)构造函数被调用。当你使用delete,也有两件事发生:针对此内存会有一个(或更多〉析构函数被调用,然后内存才被释放。delete的最大问题在于:即将被删除的内存之内究竟存有多少对象。这个问题的答案决定了有多少个析构函数必须被调用起来。实际上这个问题可以更简单些:即将被删除的那个指针,所指的是单一对象或对象数组?这是个必不可缺的问题,因为单一对象的内存布局一般而言不同于数组的内存布局原创 2021-05-07 11:12:25 · 111 阅读 · 0 评论 -
Effective C++ 详解条款15: 在资源管理类中提供对原始资源的访问
假期归来第一天!!!!学习起来up up up ღ( ´・ᴗ・` )ღ比心由条款13导入一个例子:使用智能指针如auto_ptr或tr1: :shared ptr保存factory函数如createInvestment的调用结果:std::tr1::shared_ ptr<Investment> pInv (createInvestment()); //见条款13假设你希望以某个函数处理Investment对象,像这样:int daysHeld (const Investment*.原创 2021-05-06 20:54:57 · 183 阅读 · 0 评论 -
Effective C++ 详解条款14: 在资源管理类中小心coping行为
许多资源被动态分配于堆 heap 内而后被用于单一区块或函数内。它们应该在控制流离开那个区块或函数时被释放。标准程序库提供的auto_ptr 正是针对这种形势而设计的。条款13就描述了auto_ptr和 tr1 : :shared_ptr是如何将“资源取得时机便是初始化时机(Resource Acquisition Is Initialization,RAII)”表现在基于堆(heap-based)资源上。然而并非所有资源都是heap-based,对那种资源而言,像auto_ptr和 tr1 : :sh原创 2021-05-04 18:54:13 · 403 阅读 · 1 评论 -
Effective C++ 详解条款13:以对象管理资源(不是只会用delete就够了!)
本条款建议,如果你打算手工释放资源(例如使用delete而非使用一个资源管理类; resource-managing class),容易发生某些错误。罐装式的资源管理类如auto_ptr和 tr1 : :shared_ptr往往比较能够轻松遵循本条款忠告。void f( ){ Investment* pInv = createInvestment ( ); //调用factory函数 ... delete pInv; //释放pInv原创 2021-05-03 21:48:44 · 170 阅读 · 1 评论 -
你会copying了吗?(Effective C++ 12 复制对象时勿忘其每一个成分)
12. 复制对象时勿忘其每一个成分为derived class写copying函数时,必须很小心地复制其base class成分。那些成分往往是private,故无法直接访问它们,应该让derived class的copying函数调用相应的base class函数。让copy assignment操作符调用copy构造函数是不合理的,因为就像试图构造一个已经存在的对象;让copy构造函数调用copy assignment操作符也同样无意义。构造函数用来初始化新对象,而 assignment操作符只.原创 2021-04-06 20:45:05 · 180 阅读 · 0 评论 -
operator= 中的“自我赋值”(Effective C++ 学习笔记详解11)
11:在operator= 中处理“自我赋值”自我赋值发生在对象被赋值给自己,class widget { ... };widget w;...w= w; //赋值给自己a[i] = a[j]; //潜在自我赋值(i=j)*px = *py; //潜在自我赋值(px和py相同)如果尝试自行管理资源,可能会掉进“在停止使用资源之前意外释放了它”的陷阱。假设你建立一个class用来保存一个指针指.原创 2021-04-05 11:05:01 · 479 阅读 · 0 评论 -
Effective C++ 关于operator(学习笔记详解09-10)
09:绝不在构造和析构过程中调用virtual函数1.base class构造函数执行早于derived class构造函数,当base class构造函数执行时derived class的成员变量尚未初始化。2.同样地,一旦derived class构造函数开始执行,对象内的derived class成员变量便呈现未定义值。在构造和析构期间不要调用virtual函数,因为这类调用从不下降至derived class。10. 让operator=返回一个reference to *th.原创 2021-04-04 17:21:18 · 171 阅读 · 0 评论 -
Effective C++ (学习笔记详解08)
Effective C++ (学习笔记详解)08:别让异常逃离析构函数如果析构函数必须执行一个动作,而该动作可能会在失败时抛出异常,例如class DBConn{ //class 用来管理DBConnetive对象public: ~DBConn(){ //确保db总能被关闭。但是一旦调用产生异常,析构函数就会传播该异常 db.close(); }private: DBConnetive db;};两个办法避免该问题。DBConn的析构函数可以原创 2021-04-03 14:32:27 · 116 阅读 · 0 评论 -
Effective C++ (学习笔记详解07)
07:为多态基类声明virtual析构函数当派生类对象经由一个基类指针被删除,而该基类带着一个非虚析构函数,其结果未有定义。因为实际执行时,通常对象的派生类成分没被销毁。解决办法:给基类一个虚析构函数。如果一个类不含虚函数,通常表示它并不想被用作一个基类,此时令其析构函数为virtual是一个馊主意。polymorphic(多态性质的)base classes应该声明一个virtual析构函数。如果class带有任何virtual函数,它就应该拥有一个virtual析构函数。classes设计原创 2021-04-02 16:24:00 · 108 阅读 · 0 评论 -
Effective C++ (学习笔记详解05-06)
文章目录05 :了解C++默默编写并调用哪些函数06: 若不想使用编译器自动生成的函数,就该明确拒绝。05 :了解C++默默编写并调用哪些函数空类Empty class,C++处理之后,如果你没有自己声明,编译器就会它声明一个拷贝构造函数,拷贝赋值函数和析构函数,甚至是default构造函数。所有这些函数都是public且inline的。如果你写了,class Empty{ }; 经过C++处理后相当于:class Empty{public: Empty(){...};原创 2021-03-27 09:27:09 · 194 阅读 · 0 评论 -
Effective C++ (学习笔记详解04)
文章目录04 确定对象被使用前已先被初始化1. 内置类型2. 非内置类型3. 跨编译单元之初始化次序总结04 确定对象被使用前已先被初始化1. 内置类型读取未初始化的值会导致不明确的行为。比如:int x;在某些语境下x保证被初始化(为0),但在其他语境中却不保证。处理办法:永远在使用对象之前先把它初始化。对于无任何成员的内置类型,必须手工初始化。int x = 0; //对int进行手工初始化const char* text = "A原创 2021-03-26 15:49:16 · 312 阅读 · 0 评论 -
Effective C++ (学习笔记详解 01~03)
Effective C++ (学习笔记详解)文章目录Effective C++ (学习笔记详解)01 :视C++为一个语言联邦02: 尽量const、enum、inline替换#define1、const2、enum3、inline03 :尽可能使用const1、**`const`语法使用**2、STL迭代器3、const成员函数01 :视C++为一个语言联邦C++的四个次语言:C:C++是在C语言的基础上发展而来的;Object-Oriented C++:这是C++中不同于C的部分,这里原创 2021-03-26 09:41:39 · 346 阅读 · 0 评论