More Effective C++读书笔记(一)

条款1:指针与引用的区别

1、二者之间的区别是:在任何情况下都不能用指向空值的引用,而指针则可以;指针可以被重新赋值以指向另一个不同的对象,但是引用则总是指向在初始化时被指定的对象,以后不能改变

2、在以下情况下使用指针:一是存在不指向任何对象的可能性;二是需要能够在不同的时刻指向不同的对象

3、在以下情况使用引用:总是指向一个对象且一旦指向一个对象之后就不会改变指向(const);重载某个操作符时,使用指针会造成语义误解。当你重载某个操作符时,你应该使用引用。最普通的例子就是操作符[]。这个操作符典型用法是返回一个目标对象,其能被赋值

4、应该远离这样的代码:char* pc = NULL; char& rc = *pc; 

5因为引用肯定会指向一个对象,在C++里,引用应该被初始化

6、不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针要高。因为使用引用之前不需要测试它的合法性。如下:引用不用检测是否为空,而指针需要。

void Test(const  int& count)

{

    cout<< count << endl;

}

 

void Test(const int* count)

{

    if(NULL !=count)

    {

        cout<< count << endl;

    }

}

 

条款2:尽量使用C++风格的类型转换

1.C++中引进四个新的类型转换操作符克服了C风格类型转换的缺点1-过于粗鲁,能允许你在任何类型之间进行转换;2-在程序语句中难以识别;3 类型转换失败不可获知),这四个操作符是,static_cast/const_cast/dynamic_cast/reinterpret_cast
2.static_cast
在功能上基本上与C风格的类型转换一样强大,含义也一样。它也有功能上限制。如你不能用static_cast象用C风格的类型转换一样把struct转换成int类型或把double类型转换成指针类型
3.const_cast
用于类型转换掉表达式的constvolatileness属性
4.dynamic_cast
用于安全地沿着类的继承关系向下进行类型转换。失败的话将返回空指针(当对指针类型进行转换时)或抛出异常(当对引用进行类型转换时)。dynamic_casts在帮且你浏览继承层次上是有限制的。它不能被用于缺乏虚函数的类型上(见条款24),也不能用它来转换掉constness
5.reinterpret_cast
,这个操作符的类型转换,其转换结果几乎都是执行期定义。因此,使用reinterpret_cast的代码很难移植。最普通的用途就是在函数指针类型之间进行转换

6、新的转型动作既丑陋又不易键入,或许未尝不是件好事,意思是尽量不要使用转型操作,和effective C++中关于转型的介绍类似。

 

条款3:不要使用多态性数组

1、多态和指针算法不能混合在一起使用,所以数组和多态也不能用在一起。

class BST { ... };

class BalancedBST: public BST { ... };

 

void printBSTArray(ostream& s,const BST array[],int numElements)

{

    for (int i =0; i < numElements; )

    {

        s<< array[i]; //假设 BST 类重载了操作符<<

    }

}

2、数组中各元素的内存地址是数组的起始地址加上之前各个元素的大小得到的,如果父类和子类各元素大小不一,那么编译器将不能正确地定位元素,从而产生错误。

3、不只是调用方面,如果尝试通过base class指针删除一个由derived class objects组成的数组,同样会出现这种问题。

4、值得注意的是如果你不从一个具体类(concrete classes) (例如 BST)派生出另一个具体类(例如 BalancedBST),那么你就不太可能犯这种使用多态性数组的错误

 

条款4:避免无用的缺省构造函数

1.在一个完美世界里,无需任何数据即可建立对象的类可以包含缺省构造函数,而需要数据来建立对象的类则不能包含缺省构造函数,唉!可是我们的现实世界是不完美的,所以我们必须考虑更多的因素。特别是如果一个类没有缺省构造函数,就会存在一些使用上的限制

第一种问题:建立对象数组时。一般来说,没有一种办法建立对象数组时给构造函数传递参数。不过还是有三种方法可以避开这个限制:

一、使用非堆数组(non-heap arrays)。缺点:不能用在堆数组(heap arrays)的定义上

二、利用指针数组来代替一个对象数组。缺点:(1)容易发生内存泄漏 (2)增加了内存分配量

三、为数组分配raw memory,使用placement new方法。缺点:不熟悉,使用不方便

第二种问题:无法在许多其于模板(template-based)的容器里使用。因为实例化一个模板时,模板的类型参数应该提供一个默认的缺省构造函数,这是一个常见的要求

第三种问题:设计虚基类时所面临的要提供缺省构造函数还是不提供的两难决策。不提供缺省构造函数的虚基类,很难与其合作。因为几乎所有的派生类在实例化时都必须给虚基类构造函数提供参数。这就要求所有由此虚基类继承下来的派生类(无论有多远)都必须知道并理解提供给虚基类构造函数的参数的意义。

2.提供无意义的缺省构造函数也会影响类的工作效率。如果成员函数必须测试所有的部分是否都被正确的初始化,那么这些函数的调用者就得为此付出更多的时间,而且还得付出更多的代码,它们也得在测试失败的地方放置代码来处理错误。如果一个类的构造函数能够确保所有的部分被正确的初始化,所有这些弊病都能够避免。缺省构造函数一般不会提供这种保证,所以在它们可能使类变的没有意义时,尽量去避免使用它们

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值