学习c++的童鞋们,这本书不能错过,最近在学校图书馆借来这本书,准备好好啃啃它了,先把它的基本内容过一遍吧。

改变旧有的的C习惯

条款1:尽量以const和inline取代#define。

条款2:尽量以<iostream>取代<stdio.h>

条款3:尽量以new和delete取代malloc和free。

条款4:尽量使用C++风格的注释形式。

条款5:使用相同形式的new和delete。

内存管理篇

条款6:记得在destructor中以delete对付pointer  members。

条款7:为内存不足的状况预做准备。

条款8:撰写operator new和operator delete 时应遵行的公约。

条款9:避免遮掩了new的正规形式。

条款10:如果你写了一个operator new,请对应写一个operator delete。

对于条款1就没什么好说的了,建议我们不要使用宏,改用常量,如const double ASPECT_RACIO=1.653,取代define  ASPECT_RACIO   1.653。

条款2是对于输入输出而言,我们应该尽量采用cin,cout。

条款3说明在c++中尽量用new取代malloc,如string *stringArray2=new string[10],当释放内存时delete[]stringArray2,数组中的每个对象的destructor都会被调用一遍。

条款10对于分配内存进行了详细的说明,我们自己写operator new的时候,一定不要忘了写operator  delete,否则就Memory leak了。

下面看段代码,书上说的是写一个Pool类来配置内存,由它负责申请和释放内存,首先定义一个Pool类。

class  Pool
{
public:
Pool(size_t n); //首先声明需要空间的大小
void *alloc(size_t n); //申请内存
void free(void *p,size_t n); //释放内存
~ Pool();
}; class AirPlane
{
public:
AirPlane();
~ AirPlane();
static void* operator new(size_t size);
static void operator delete(void *p,size_t size); private:
AirPlaneRep* rep;
static Pool memPool; }; inline void* AirPlane::operator new(size_t size)
{
return memPool.alloc(size);
}
inline void AirPlane::operator delete(void *p,size_t size)
{
return memPool.free(p,size);
} Pool AirPlane::memPool(sizeof(AirPlane)); //用sizeof()初始化memPool,大小为一个Airplane;

 通过这种方法可以改善程序效率,重点还是需要operator new和operator delete 二者合作。

条款11:如果class内动态配置有内存,请为此class声明一个copy constructor和一个assignment运算符。这就话也可以这么理解,当你的class中拥有任何指针的时候,那么类最好拥有自己的copy constructor和assignment operator。

class  TableString
{
public:
TableString(const char*);
~ TableString(); private:
char* data;
}; TableString:: TableString(const char*value)
{
if (value)
{
data=new char[strlen(value)+1];
strcpy_s(data,strlen(value)+1,value);
}
else
{
data=new char[1];
*data='\0';
}
} TableString::~ TableString()
{
delete[]data;
}
int _tmain(int argc, _TCHAR* argv[])
{
TableString a("hello");
TableString b("nihao");
b=a;
return 0;
}

  例如上面这段代码里面,类TableString有自己的指针变量,却没有定义自己的复制构造函数和赋值函数,当执行完b=a这一句的时候,内存就已经泄漏了。首先,b原先的内存没有释放,其次,a和b的指针指向相同的字符串,当其中一个离开生存空间,就会调用它的析构函数,删除内存,另外一个指针指向的内存就为空了。

构造、析构和赋值操作

条款15:令operator==传回“*this的reference”

String& String::operator=(const String& rhs)
{
return *this; //传回一个引用,指向左侧对象
}
String& String::operator=(const String& rhs)
{
return rhs; //指向右侧对象
}

  定义的第二个赋值操作符将无法通过编译,因为rhs是一个引用型const常量,而传回的却是非const引用,而我们把const去掉的话也不能解决问题,不能把const常量传递给非const的参数变量。所有,我们别无选择,只能return *this。

条款16:在operator=中为所有的datamembers设定(赋值)内容

这个条款大概的意思就是在派生类中必须对基类的成员进行一个初始化,在派生类的构造函数中可以调用基类的构造函数进行成员的初始化,为base制定初值。

条款17:在operator=中检查是否“自己赋值给自己”

成员在赋值的时候,又可能出现自己赋值给自己的情况,例如:String a="hello world";a=a;如果你在赋值运算符中没有对这个进行检验的话,那么程序写出来后果将不堪设想。我们一般的做法是看它们的内存地址是否相等。例如:

C& C::operator=(const C& rhs)
{
if (this==&rhs)
{
return *this;
}
}

  这对许多程序而言都足够了。

Effective C++ 重要条款的更多相关文章

  1. 《MORE EFFECTIVE C++》条款20 条款21

    条款20 协助编译器实现返回值优化 当重载运算符的时候,比如+ - * / 这类运算符,该函数返回的值一定是个右值(即不能是引用),那么执行一次运算的开销可能会在临时对象上调用多次构造函数和析构函数, ...

  2. 《More Effective C++》 条款5 谨慎定义类型转换函数

    ---恢复内容开始--- C++编译器能够在两种数据类型之间进行隐式转换(implicit conversions),它继承了C语言的转换方法,例如允许把char隐式转换为int和从short隐式转换 ...

  3. 《Effective C++》条款26 防卫潜伏的ambiguity模棱两可的状态

    每个人都有思想.有些人相信自由经济学,有些人相信来生.有些人甚至相信COBOL是一种真正的程序设计语言.C++也有一种思想:它认为潜在的二义性不是一种错误.ambiguity 这是潜在二义性的一个例子 ...

  4. 《Effective C++》条款14 总是让base class拥有virtual destructor

    有时,一个类想跟踪它有多少个对象存在.一个简单的方法是创建一个静态类成员来统计对象的个数.这个成员被初始化为0,在构造函数里加1,析构函数里减1.(条款m26里说明了如何把这种方法封装起来以便很容易地 ...

  5. Effective C++:条款37:绝不又一次定义继承而来的缺省參数值

    因为又一次定义继承而来的non-virtual函数是不对的(见上一个条款),所以这个条款就将问题局限于:绝不又一次定义继承一个带有缺省參数值的virtual函数. (一) virtual函数是动态绑定 ...

  6. Effective C++:条款28:避免返回 handles 指向对象内部成员

    (一) 有时候为了让一个对象尽量小,能够把数据放在另外一个辅助的struct中,然后再让一个类去指向它.看以下的代码: class Point { public: Point(int x, int y ...

  7. Effective C++:条款25:考虑写出一个不抛异常的swap函数

    (一) 缺省情况下swap动作可由标准程序库提供的swap算法完毕: namespace std { template<typename T> void swap(T& a, T& ...

  8. Effective C++:条款14:在中小企业资源管理copying表现

    (一) 在一项条款说法auto_ptr和tr1::share_ptr适合heap-based资源.然而,并非所有的资源都heap-based的.换句话说不tr1::shared_ptr 和 auto_ ...

  9. More Effective C++ 35 条款

    一.基础议题(basics) 条款1:仔细区别 pointers 和 references(Distinguish between pointers and references) 一个基本的语法问题 ...

  10. Effective C++ 50条款

    条款1:尽量用const和inline而不用#define 以const 行使常量折叠,用inline 代替常用操作的宏定义,而且库里面有很多常用函数可用.当然不能抛弃宏,宏还是很有用滴.偶最近才发现 ...

随机推荐

  1. 用位运算实现四则运算之加减乘除(用位运算求一个数的1/3) via Hackbuteer1

    转自:http://blog.csdn.net/hackbuteer1/article/details/7390093 ^: 按位异或:&:按位与: | :按位或 计算机系统中,数值一律用补码 ...

  2. python 进行web测试

    1:安装nosetests Python 单元测试框架之Nose http://blog.sina.com.cn/s/blog_65a8ab5d0101fihb.html Python nose te ...

  3. 2014年第五届蓝桥杯国赛 Log大侠(区间合并+Java递归效率分析)

    1678: Log大侠 java 时间限制: 2 Sec  内存限制: 256 MB提交: 20  解决: 1 题目描述     atm参加了速算训练班,经过刻苦修炼,对以2为底的对数算得飞快,人称L ...

  4. POJ - 2955 Brackets括号匹配(区间dp)

    Brackets We give the following inductive definition of a “regular brackets” sequence: the empty sequ ...

  5. Apt本地源制作

    方法一 缓存deb包 # apt install XXX # mkdir -p /usr/local/mydebs # find /var/cache/apt/archives/ -name *.de ...

  6. [poj]1050 To the Max dp

    Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any ...

  7. Unity ShadowMapping

    原理: 场景中一个plane,一个cube,一个light,一个mainCamera 为了在plane上呈现cube的shadow,先在light上放一个lightCamera(位置方向跟light相 ...

  8. 【Ionic+AngularJS 开发】之『个人日常管理』App(一)

      写在前面的话 过去一年自己接触了不少手机前端开发,得益于现在手机性能的提升和4G普及,感觉使用混合技术开发手机App已经可以满足越来越多的应用场景了.新年伊始,对自己2016年所学知识做一个阶段性 ...

  9. 求n位水仙花数

    求n位水仙花数 A.两个关键 1.n位水仙花数的范围是什么? n位水仙花数的范围是[10n-1,10n) 2.如何判断是否为水仙花数 核心操作: 2-1.如何得到每一位? A.核心思想 对得到的数进行 ...

  10. UVa 11168(凸包、直线一般式)

    要点 找凸包上的线很显然 但每条线所有点都求一遍显然不可行,优化方法是:所有点都在一侧所以可以使用直线一般式的距离公式\(\frac{|A* \sum{x}+B* \sum{y}+C*n|}{\sqr ...