学习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. 【转】Pro Android学习笔记(六):了解Content Provider(中)

    Content Provider的架构 Authority类似web中的域名,每个content provider会通过AndroidManifest.xml向系统注册authority,如下.其中n ...

  2. .NETFramework:WebClient

    ylbtech-.NETFramework:WebClient 1.程序集 System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5 ...

  3. 6 git 生成SSH公钥/私钥 查看公钥

    如果没有公钥的话就生成公钥私钥:  $ ssh-keygen 然后连续回车(一次是位置,两次密码)

  4. pkg_resources----Entry Points为程序提供扩展点

    官方文档对Entry Points的介绍 Entry Points Entry points are a simple way for distributions to "advertise ...

  5. boost编译配置及简单使用

    boost编译配置及简单使用 1.下载 http://www.boost.org/ 2.编译: A.解压 boost_1_55_0.zip 到boost路径 B.运行 bootstrap.bat. 会 ...

  6. 【转】 mybatis如何在控制台打印执行的sql语句

    <strong>######################################################################### #Root Logger ...

  7. Json文件转Excel

    先创建一个web项目,在根目录放置需要转换的json文件,直接读取静态Json文件加载数据进行转换,代码如下: string Json = string.Empty; List<object&g ...

  8. 【Java面试题系列】:Java基础知识常见面试题汇总 第一篇

    文中面试题从茫茫网海中精心筛选,如有错误,欢迎指正! 1.前言 ​ 参加过社招的同学都了解,进入一家公司面试开发岗位时,填写完个人信息后,一般都会让先做一份笔试题,然后公司会根据笔试题的回答结果,确定 ...

  9. Git 时光穿梭鸡 管理修改

    Git跟踪并管理的是修改,而非文件. 什么是修改? 比如你新增了一行,这就是一个修改, 删除了一行,也是一个修改, 更改了某些字符,也是一个修改, 删了一些又加了一些,也是一个修改, 甚至创建一个新文 ...

  10. Widows下Faster R-CNN的MATALB配置(GPU)

    目录 1. 准备工作 2. VS2013编译Caffe 3. Faster R-CNN的MATLAB源码测试 说在前面,这篇是关于Windows下Faster R-CNN的MATLAB配置,GPU版本 ...