【转】effective C++读书笔记(二)

来源:互联网 发布:乐其网络双休吗 编辑:程序博客网 时间:2024/04/29 20:40

转自:http://hi.baidu.com/a024014/blog/item/617b690ac43e8b1a95ca6ba2.html

 

类和函数:设计与声明

条款18:争取使类的接口完整并且最小

条款19:分清成员函数,非成员函数和友元函数

如果f 必须是虚函数,就让它成为C 的成员函数。

operator>>operator<<决不能是成员函数。如果f operator>>operator<<,让f 成为非成员函数。如果f 还需要访问C 的非公有成员,让f 成为C 的友元函数。

只有非成员函数对最左边的参数进行类型转换。如果f 需要对最左边的参数进行类型转换,让f 成为非成员函数。如果f 还需要访问C 的非公有成员,让f 成为C 的友元函数。

Eg:

Ostream& operator<<(ostream& output,const String& str){

    Output<<String.data;//String 是自己定义的一个类

}

条款20:避免public接口出现数据成员

    这个条款其实就是让我们用get方法获取成员而避免把数据成员直接声明为public

条款21:尽可能使用const

    Const char *p; 1

    Char const *p; 2

    Char *const p; 3

    Const char *const p; 4

    其中1=2,表示指针p指向的内容是不可修改的常量;

    3表示p指向的地址是不可修改的;

    4则综合了前两者。基本上就是个就近原则,以*为分界线,const靠近谁,谁就是不可修改的。

    顺便提下,可以这样声明:

    Const int &p=3;//int &p=3;是错的

Const Char *&const p=”hello”;//const char *&p=”hello”是错的

另外,C++允许仅在const方面有不同的成员函数重载,eg:

class String {

public:

...

// 用于非const 对象的operator[]

char& operator[](int position)

{ return data[position]; }

// 用于const 对象的operator[]

const char& operator[](int position) const

{ return data[position]; }

private:

char *data;

};

String s1 = "Hello";

cout << s1[0]; // 调用非const

// String::operator[]

const String s2 = "World";

cout << s2[0]; // 调用const

// String::operator[]

当方法为const时,还要修改数据成员时,可以把数据成员修饰为mutable.

有时候,迫不得已,可以用const_castconst性转掉。

条款22:尽量用“传引用”而不用“传值”

    传递引用除了比传值高效之外,主要原因在于它避免了切割问题的出现,也就是不存在子类用父类变量传递时发生的切割,被去除了子类特有的部分,用引用实现动态绑定。

    当然在传递的变量类型很小,或者基类型时,用传值反而更快,因为引用的内部实现其实用的是指针,当charshort,int,直接传递值速度反而更快一些。

条款23:必须返回一个对象时不要试图返回一个引用

    该条款主要就是为了保证程序的正确性,防止返回一个局部对象的引用。

条款24:在函数重载和设定参数缺省值间慎重选择

`

条款25:避免对指针和数字类型重载

    Eg:void f(int x);

       Void f(string *ps);

       F(0); //调用f(int) 还是f(string *)

    上述结果是调用f(int),但是有时候我们并不希望编译程序这样理解。

    定义一个类NULL如下可以解决问题:

const // 这是一个const 对象...

class {

public:

template<class T> // 可以转换任何类型

operator T*() const // null 非成员指针

{ return 0; } //

template<class C, class T> // 可以转换任何类型

operator T C::*() const // null 成员指针

{ return 0; }

private:

void operator&() const; // 不能取其地址

// (见条款27)

} NULL; // 名字为NULL

此时调用f函数时用f(NULL) f(0)即可区分开来。

    当然,作为重载函数的设计者,归根结底最基本的一条是,只要有可能,就要避免对一个数字和一个指针类型重载。

原创粉丝点击