Effective C++
JF_Ma
好好学习,不断进步
展开
-
Effective C++ 条款50
了解new和delete的合理替换时机如题所述,我们在本节中只是了解一下什么时候需要自己写new和delete,为什么要重新写new和delete,出于什么样的动机等等。 本文重在论述,至于作者提供的程序代码也具有漏洞,本节的目的就是对new和delete有一个宏观的认识。下面是替换的原因:1.用来检测运用上的错误。如果delete new的内存失败,会导致内存泄漏。如果在new所得内存多次del原创 2015-06-16 08:54:03 · 595 阅读 · 0 评论 -
Effective C++ 条款23
宁以non-member、non-friend替换member函数本节作者阐述了为什么在实现一些功能的时候,应该偏向于选择非成员函数并且是非友元函数。这样做总结一句话,就是最大限度的实现类的封装性。封装意味着不可见。愈多东西被封装,欲少人可以看到它,我们就有愈大的弹性去改变它。愈少代码可以看到数据(访问数据),愈多数据可被封装,我们就更有自由来改变对象数据。愈多函数可以访问它,数据的封装性就愈低。我原创 2015-06-27 09:37:57 · 666 阅读 · 0 评论 -
Effective C++ 条款21
必须返回对象时,别妄想返回其reference我们上节分析了对象引用传递的好处,现在说明函数返回引用对象带来的种种坏处。 先来一段代码:class Rational{public: Rational(int numerator=0, int denominator=1); ……private: int n, d; friend const Rationa原创 2015-06-26 10:03:50 · 679 阅读 · 0 评论 -
Effective C++ 条款43
学习处理模板化基类里的名称本节作者编写的意图在我看来可以总结成一句话,就是“如何定义并使用关于模板类的派生过程,如何处理派生过程出现的编译不通过问题”。下面我们看一段说明性的代码:#include<iostream>using namespace std;class object1{public: void get(){ cout << "object1"; } void ou原创 2015-06-05 16:15:30 · 723 阅读 · 1 评论 -
Effective C++ 条款20
宁以pass-by-reference-to-const替换pass-by-value本节,我们一起来探究一下值传递和引用传递之间的区别。 先看一段代码:class Person{public: Person(); virtual ~Person(); ……private: std::string name; std::string address;}原创 2015-06-26 08:48:33 · 677 阅读 · 0 评论 -
Effective C++ 条款42
本节条款我们讨论一下class 关键字和typename关键字的不同以及对于模板函数(template function)的影响。 如下代码:template<class T>T getValue1(T m){ return m * 2;}template<typename T>T getValue2(T m){ return m * 2;}在上面代码中,class和t原创 2015-06-04 12:47:18 · 737 阅读 · 2 评论 -
Effective C++ 条款18
让接口容易被正确使用,不容易被误用如题目,我们自己的程序接口是面向用户的,程序的目的不但是解决问题,而且要让用户容易使用,所以,必须保证我们的程序接口具有很强的鲁棒性。怎么保证接口的鲁棒性,不同情况有不同的处理结果,作者列出了以下几个例子所对应的方法。1.设计一个class来表示日期class Date{public: void Date(int month, int day, int year原创 2015-06-25 16:14:01 · 518 阅读 · 0 评论 -
Effective C++ 条款17
以独立语句将newed对象置入智能指针本节我们需要学习的知识核心是注意编译器在同一语句中,调用次序具有不确定性,不同语句中,调用次序确定。 上面的话什么意思? 请看以下代码:int priority();int processWidget(shared_ptr<Widget> pw, int priority);processWidget(shared_prt<Widget> pw(new原创 2015-06-24 15:43:41 · 578 阅读 · 0 评论 -
Effective C++ 条款41
本节条款对比了一下两对概念的对比。 首先是 编译期多态和运行期多态。 接着是 显示接口和隐式接口编译期多态是由于模板而产生的。 如下代码:#include<iostream>using namespace std;class Bird{public: Bird(int v):value(v){} int getSize(){ return value; }privat原创 2015-06-04 10:01:47 · 771 阅读 · 2 评论 -
Effective C++ 条款19
设计class犹如设计type定义一个class,定义一个好的class需要考虑很多条件。1.新type的对象应该如何被创建和销毁?2.对象初始化和对象赋值该有什么样的区别?3.新type的对象如果被pass by value,意味着什么?4.什么是新type的合法值?5.新type需要配合某个继承图系(inheritance graph)吗?6.新type需要什么样的转换?7.什么样的操作符和函数原创 2015-06-25 16:18:33 · 376 阅读 · 0 评论 -
Effective C++ 条款16
成对使用new和delete时要采取相同形式本节条款知识点在于delete和delete[]的区别 大家都知道在new一个对象的时候要delete一个对象,在new 一个对象数组时要delete[]才是正确的。大家也知道new产生两个行为,一个是申请对象所需内存,另一个是调用类构造函数初始化对象。 那么,delete的行为也有两个,一个是调用对象的析构函数,另一个是回收内存。而new[]是对每个原创 2015-06-24 14:37:20 · 434 阅读 · 0 评论 -
Effective C++ 条款24
若所有参数皆需类型转换,请为此采用non-member函数我们直奔主题 如果你定义一个有理数类如下class Rational{public: Rational(int numerator=0, int denominator=1);//非explicit,允许隐式转换 const Rational operator*(const Rational& rhs); ..原创 2015-06-27 16:26:15 · 552 阅读 · 0 评论 -
Effective C++ 条款25
考虑写出一个不抛出异常的swap函数本节讲解如何自定义一个高效的swap函数对于std名空间中的swap缺省函数如下所示namespace std{ template<typename T> void swap(T& a, T& b) { T temp(a); a=b; b=temp; }}class WidgetIm原创 2015-06-27 20:34:56 · 956 阅读 · 0 评论 -
Effective C++ 条款22
将成员变量声明为private本节条款,作者花了很大的篇幅去介绍,可是我感觉就学到一句话。 那就是注意程序的封装性。 程序的封装性起到什么作用?很明显是保护数据操作的安全性以及增强以后程序的可维护性。将类的数据成员声明为private的,可以保护数据不被随便修改。大家都明白权限等级就是安全等级。至于程序的可维护性,就是用良好的函数接口代替直接的数据成员的操作,这样不但编写的时候方便,而且在修改程原创 2015-06-26 10:44:07 · 614 阅读 · 0 评论 -
Effective C++ 条款49
了解new-handler的行为本节条款讲述的技术是,在operator new抛出异常以前,会先调用一个客户指定的错误处理函数:new-handler。当内存分配失败的时候如何自定义并使用这个内存异常处理函数。关键语句就是set_new_handler。作者重点强调如何对于class的内存分配,实现不同的内存分配错误处理函数。 我们先来举个书上的例子,先弄明白如何使用new-handler技术。原创 2015-06-15 10:35:57 · 636 阅读 · 0 评论 -
Effective C++ 条款48
本节条款:了解模板元编程本节条款是对模板元编程的简单介绍,让读者知道有这么一种编程方式,更确切的说是一种技术。 那么,什么是模板元编程?模板元编程有什么好处?按照作者的原话就是: 1. TMP可将工作由运行期转移到编译期,因而得以实现早期错误侦测或者更高的执行效率。 2. TMP可被用来生成“基于政策选择组合”的客户定制代码,也可以用来避免生成对某些特殊类型并不适合的代码。 说原理容易让人不原创 2015-06-11 09:52:35 · 912 阅读 · 0 评论 -
Effective C++ 条款28
避免返回handles指向对象内部成分本节作者讲述的知识核心是对于一个类来说,应该避免类返回自己内部的私有数据。 如下:class Point{public: Point(int x, int y); …… void setX(int newVal); void setY(int newVal); ……};struct RectData{ Poi原创 2015-06-30 14:48:58 · 677 阅读 · 0 评论 -
Effective C++ 条款47
本节条款的题目:请使用trait classes来表示类型信息本节条款主要讲述的技术是如何在编译期间实现对迭代器类型的判断,根据判断的类型进行最优处理。 我们先来看一下迭代器的种类: 1.input_iterator:只读,只能逐个前移 2.output_iterator:只写,只能逐个前移 3.forward_iterator:可读可写,只能逐个前移 4.bidirectional_it原创 2015-06-09 11:07:29 · 941 阅读 · 2 评论 -
Effective C++ 条款27
尽量少做转型动作尽量少做转型动作有什么目的?很明显无非就是提高程序的稳定性,提高程序的执行效率。 那么,有哪些转型方式?每种方式都有什么弱点? 这是我们本节学习的重点。 C++有四种转型:const_cast<T>(expression)dynamic_cast<T>(expression)reinterpret_cast<T>(expression)static_cast<T>(expr原创 2015-06-29 10:54:44 · 691 阅读 · 1 评论 -
Effective C++ 条款26
尽可能延后变量定义式的出现时间我们知道定义一个对象的时候有一个不争的事实,那就是分配内存。如果是我们自定义的对象,程序执行过程中会调用类的构造函数和析构函数。我们打个比方,如果天下雨了,你带把雨伞肯定是值得的。但是,如果你带伞了,今天却没下雨,你是不是感觉自己亏了?的确,亏在了带了却没用,所以伞就变成了累赘。本节的关键就在于此,如果你定义一个变量或者对象没有被使用,那么就是不完美的代码。 我们看一原创 2015-06-29 09:00:26 · 907 阅读 · 0 评论 -
Effective C++ 条款46
本节条款:需要类型转换时请为模板定义非成员函数这节知识是在条款24的基础上,讲述的有关非成员函数在模板类中(non-member function template)的作用。 我们先看一下条款24讲述的知识核心。条款24讲述了我们如何能实现类的对象在特定条件下的隐式转换问题。 我们先看以下代码:**例一:**#include<iostream>#include<assert.h>using原创 2015-06-08 10:48:26 · 1022 阅读 · 1 评论 -
Effective C++条款45 附加代码
本节是对上一篇博客的附加代码,基本的45条款思想已经实现。#include<iostream>using namespace std;template<typename T>class SharedPtr{public: template<typename U> SharedPtr(const SharedPtr<U>&u) :ptr(u.get()) {原创 2015-06-07 15:56:01 · 599 阅读 · 1 评论 -
Effective C++ 条款45
本节条款的题目是运用成员模板接受所有兼容类型作者阐述自己的观点是通过智能指针的例子。 在学习本节条款之前我们要先明白关于隐式转化的问题 如下代码:#include<iostream>using namespace std;class A{public: explicit A(int i):a(i){}; A(const A&obj):a(obj.a) {原创 2015-06-07 15:31:38 · 812 阅读 · 1 评论 -
Effective C++ 条款44
本节条款的标题是:将与参数无关的代码抽离templates学习本节条款首先需要明白一件事情,那就是模板实例化的过程会不会重复? 我们来举个例子:#include<iostream>using namespace std;template <typename T>T Try(T m){ return m;}int main(){ Try(10); Try(1);}原创 2015-06-06 15:51:24 · 1278 阅读 · 1 评论 -
Effective C++ 条款15
在资源管理类中提供对原始资源的访问前面两节都在讨论如何管理资源,一般情况下,使用资源管理类来屏蔽原始资源,对抗内存泄露等问题,避免使用原始资源。这样我们就无法直接访问原本的原始资源。毕竟程序在有些时候是需要操纵原始资源的,许多APIs要求使用原始资源。为了能操纵原始资源,我们要怎么做? 还好,shared_ptr和auto_ptr都提供一个get函数,用于执行这样的显示转换。这时如果在调用API时原创 2015-06-24 10:52:43 · 864 阅读 · 0 评论 -
Effective C++ 条款13
以对象管理资源资源的种类很多,动态分配的内存、文件描述器、互斥锁、图像界面中画刷、数据库连接、网络socket等。资源一般是有限的,当你不用时,必须释放。不然就会造成资源浪费,更严重的情况下,非法占有所有资源导致程序崩溃。那么我们怎么样才能合理使用资源?换句话说我们应该怎么样才能做到资源的释放? 本节的核心点是:利用析构函数自动调用机制实现资源的合理释放。举个例子:class Investment原创 2015-06-24 09:56:08 · 593 阅读 · 0 评论 -
Effective C++ 条款3
尽可能使用constconst关键字在编程中的应用广泛,如何灵活的发挥它的优势值得我们探讨,首先理解什么是const,如何使用const。 我们看一下对于一个指针有关const的应用。char g[]="hello";char *p=g;const char *p=g;//该指针指向的数据不可修改char *const p=g;//该指针自身的值不能修改const char * const原创 2015-06-20 09:45:22 · 854 阅读 · 8 评论 -
Effective C++ 条款6
若不想使用编译器自动生成的函数,就该明确拒绝本节知识点是 如果不想让编译器自动生成copy函数和copy assignment函数。我们就可以通过以下两种方式实现第一种: 将copy函数和copy assignment函数声明为private成员,并且不实现它们。这样只要调用此类函数编译器就无法通过编译。如果别的成员函数调用它们,则连接器无法通过连接。 如下代码:class HomeForSa原创 2015-06-21 09:58:27 · 668 阅读 · 0 评论 -
Effective C++ 条款5
了解C++默认编写并调用哪些函数本节有两处知识点。首先 对于一个class 1.如果class中没有任何构造函数,那么编译器为class声明一个default默认构造函数。 2.如果class没有析构函数、copy构造函数、copy assignment运算符则class声明这三个函数。 3.只有当调用析构函数、copy构造函数、copy assignment运算符时,编译器才生成它们,请大原创 2015-06-21 09:06:19 · 1029 阅读 · 1 评论 -
Effective C++ 条款2
尽量以const、enum、inline替换#define首先,大家要明白一个道理。#define是什么,有什么作用。很简单,大家都知道#define实现宏定义,如下代码:#define Flag 10以后Flag的地方,预处理器都用10来代替,试想一下,如果你的函数中不小心定义了一个Flag,而你的用意只是一个局部变量,那么程序会出现什么问题#define Flag 10#include<ios原创 2015-06-19 12:06:53 · 784 阅读 · 0 评论 -
Effective C++ 条款32
Effective C++ 32Public继承在c++中的作用: 如果derived class继承类通过public继承方式继承自base class基类,那么程序员就默认基类的功能在派生类中都能实现。否则这种继承就是失败的继承。 举个例子,鸵鸟和鸟的关系。在现实生活中可以认为这种继承关系是对的,自然的。可是,在C++程序中这种关系却可能存在问题。 比如,飞行功能fly()被认原创 2015-05-29 11:25:41 · 618 阅读 · 3 评论 -
Effective C ++ 条款34
该条款讲的内容就是以下3点: 第一点: pure virtual 成员函数的作用,纯虚函数的作用就是base class基类提供给derived class 派生类一个接口,而且只是起到接口的目的。 举到例子,class picture{ public: virtual void Drew()=0;};class picture1:public picture{原创 2015-05-31 10:30:15 · 590 阅读 · 2 评论 -
Effective C++ 条款1
视C++为一个语言联邦本节是Effective C++这本书的第一节,内容就是对C++语言的特性的描述,其实C++的特性是多样的,它不同于java,java是纯正的面向对象语言,而对于C++来说,面向对象只是其中一个主要的特征。C++实在C的基础上发展而来,C++是兼容C的特征,C是面向结构化的语言,它的侧重点在于算法和数据结构。编写C代码,侧重点在于通过输入数据,设计一定的算法过程,得到输出。可以原创 2015-06-19 08:06:51 · 1030 阅读 · 0 评论 -
Effective C++ 条款54-55
条款54本书中的C++规范是在1998年制定的。现在C++11,即C++0x已经制定,且C++14在讨论中。本条款讨论内容是关于Boost库的,当时没有制定新标准,一些语言上的新特性以技术报告内容程序给大家,TR1代表Technical Report 1。现在来看一下C++98加如的标准程序库有哪些:STL,即Standard Template Library标准模板库。 iostreams,包含转载 2015-06-18 10:44:48 · 465 阅读 · 0 评论 -
Effective C++条款53
不要轻忽编译器的警告编译器的警告对于有些程序员来说并不在意。他们认为警告并不威胁程序或者对程序来说没有什么太大的副作用。然而,这种想法在编程的时候可能会付出很大的代价。 如下例子:class B{ public: virtual void f() const; }; class D: public B{ public: virtual原创 2015-06-18 08:54:08 · 560 阅读 · 0 评论 -
Effective C++ 条款52
写了placement new也要写placement delete本文主要内容是对placement new 和 placement delete的介绍,以及在什么情况下使用placement new和placement delete。对于语句Widget* pw=new Widget;来说,该语句做了两件事情,第一件事情是申请了内存区域;第二件事情是在该内存区上进行对象的构造,即调用构造函数。我原创 2015-06-17 09:53:37 · 792 阅读 · 0 评论 -
Effetive C++ 条款4
确定对象使用前已先被初始化我们都明白如果程序中使用了未经初始化的数据成员,那么程序将会出现非预期的错误结果。 本节就是说明如何初始化的一般方法首先对于一个class来说,它的初始化使用成员初始化列进行,构造函数中所谓的“初始化”是赋值。如下,前者是初始化后赋值,后者是直接初始化。class P{public: P(int x0, int y0) { x=x0;原创 2015-06-20 11:07:29 · 412 阅读 · 0 评论 -
Effective C++ 条款35
本条款作者所要表达的用意就是对于virtual成员函数的功能实现可以以其他形式代替。有的时候单纯的virtual函数可能无法满足真实编程的需要。 第一种方法: 定义一个private virtual函数,再定义一个non-virtual函数,non-virtual函数调用private virtual函数实现功能。 代码如下:class person{public:virtual int原创 2015-06-01 10:28:30 · 551 阅读 · 2 评论 -
Effective C++条款7
为多态基类声明virtual析构函数本节重点大家只要明白为什么要声明析构函数为virtual函数,即声明virtual析构函数的意义。我们知道,析构函数的作用就是实现多态polymorphic。那么如果我们动态创建一个derived派生类,由基类指针接受该派生类地址。那么我们如何释放这个派生类的内存? 如下代码:class A{//...........};class B:public A原创 2015-06-22 09:28:44 · 494 阅读 · 0 评论 -
Effective C++ 条款51
编写new和delete时需固守常规本章节介绍在自定义new和delete函数时,应该需要遵守哪些要求,为什么遵守这些要求。首先,如下代码所述,当我们定义new的时候需要把size为0的内存申请考虑进去,为什么当内存申请为0时却分配1个字节的内存。大家想一下当你定义一个空的classA时,sizeof(A)占据大小是多小?很显然占据1个字节的空间,这是系统分配内存时在这种情况下遵守的规则,我们可以自原创 2015-06-17 08:43:31 · 805 阅读 · 0 评论