高质量C++编程指南学习笔记第11章---thanks to林锐

来源:互联网 发布:js textarea 换行符 编辑:程序博客网 时间:2024/05/21 09:05

第十一章     其他编程经验

111利用const提高函数的健壮性

         const更大的魅力是它可修饰函数的参数、返回值、甚至函数的定义体。

11.1.1const修饰函数的参数

若参数作输出用,无论是指针传递还是引用传递,都不能加const修饰,否则该参数将失去输出功能。const只能修饰输入参数:

Ø  若输入参数采用“指针传递”,则加const修饰可防止意外改动该指针。指针传递本质也是值传递,若使用指针常量,因调用时还要产生参数的副本,则其const将会失效,所以输入参数是常量指针而非指针常量。const*前为常量指针,在其后为指针常量。

Ø  若输入参数采用“值传递”,因函数将自动产生临时变量用于复制该参数,该输入参数本来就无须保护,所以不要加const修饰。

Ø  对非内部数据类型的参数而言,像void Fun(A a)这样的声明注定效率较低。因函数体内将产生A类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都需要时间。为提高效率,可将声明改为void Fun(A &a),因引用传递不需产生临时对象。缺点:引用传递可能改变参数a,所以需改为void Fun(const A &a)。对内部数据类型,因不存在构造析构过程,所以不需改为引用传递。简而言之,即对非内部数据类型,应将“值传递”方式改为“const引用传递”方式。对内部类型,使用“值传递”。

11.1.2const修饰函数的返回值

上面讲了输入参数的三种传递方式,函数的返回值也有三种方式,同输入参数的方式。

Ø  若给以“指针传递”方式的函数返回值加const修饰,那么函数返回值的内容不能被修改,该返回值只能赋给const修饰的同类型指针。例如:const char *GetString(void);

char *str = GetString();----------------------编译错误

const char *str = GetString();----------------正确

因不可将指向常量的指针赋给非指向常量的指针。

Ø  若返回值用“值传递”方式,因函数会把返回值复制到外部临时的存储单元中,加const修饰无意义。对非内部数据类型,可采用“const引用传递”,注意引用不能指向函数的局部变量,否则出错。

Ø  函数返回值采用“引用传递”的场合不多,一般仅用于类的赋值函数中,以实现链式表达。

11.1.3const成员函数

任何不会修改数据成员的函数都应该声明为const类型。若在编写const成员函数时,不慎修改了数据成员或调用了非const成员函数,编译将报错。声明格式如:

class Stack

{

public:

         int Pop(void);

         int GetCount(void) const;//const成员函数

private:

         int m_num;

};

int Stack::GetCount(void) const

{

         ++m_num;                                    //编译错误

         Pop();                                             //编译错误

         return m_num;

}

 

总结:const的用法:修饰函数函数参数、返回值、函数体本身。

对参数和返回值的传递方式,都有三种:指针传递、值传递、引用传递。

参数:const修饰输出参数无意义,仅修饰输入参数。const指针传递:可防止修改输入参数;值传递:const修饰无意义;const引用传递:对非内部数据参数有用,可避免产生临时对象,提高效率。

返回值:const指针传递:返回值内容不能被修改,只能赋给同类型的const指针;值传递:因要生成临时对象,const修饰无意义;const引用传递:对非内部数据有用,一般仅用于类的赋值函数中。注意指针传递和引用传递,返回值不要指向局部变量。

函数体本身:不修改数据成员就声明为const成员函数,其内部不可改变数据成员,也不可调用非const成员函数。

区分:指向常量的指针const int *p;指针常量int *const p;

原创粉丝点击