现在的位置: 首页 > 综合 > 正文

const小结

2014年02月21日 ⁄ 综合 ⁄ 共 2325字 ⁄ 字号 评论关闭
    C++中的const意味着只读,合理的使用const将大大改善程序的健壮性:

1)声明一个参数为常量是可以向用户传达有用的信息,告知这个参数的应用目的。在规模稍大一点的软件开发中,可以减少阅读程序的人的困惑,避免其他接手工作的程序员花时间清理无用的垃圾。懂得用const的程序员很少会留下的垃圾让别人来清理。
2const关键字通过给优化器一些附加的信息,产生更紧凑的代码。
3)合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改,减少bug的出现。

1
const的基本概念

    请看下面代码段:

const int a;
int const a;
const int *a;
int * const a;
int const * a const;

    如果关键字不涉及指针,很好理解。前两个其实一个意思,a是一个常整型数。

    后面三句出现了指针,就有点意思了。参考《Effective C++》中所述,若const”*”的左边,则const修饰指针所指向的变量;若const”*”的右边,const就是修饰指针本身,即这个指针是个常指针。因此,第三句意味着a是一个指向常整型数的指针(整型数是不可修改的,但指针可以指向其他地址)。第四个意思a是一个指向整型数的常指针(即指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(即指针指向的整型数是不可修改的,同时指针也是不可修改的)。

    const还可修饰函数的参数和返回值;对于类,const可以修饰成员变量和成员函数(const成员变量通常由const成员函数访问)。偶就不一一举例了。


2
,定义const变量

    不涉及指针的const变量的定义很简单,没什么陷阱。因此我重点总结一下涉及指针和引用的const变量定义中需要注意的问题。

1

int a = 10;
const int * p = &a;
int * q = p;

    上面的例子中,整型变量a的值为10p被定义为一个指向const的变量的指针,p认为它所指向的变量不能改变。从某种角度讲,这个指针都失去了其意义(因为通常我们使用指针都是希望通过指针对变量进行修改,但是这里指针指向的是const变量)。

    但是,请注意,a本身并不是const,并且上例中的q也不是指向const。因此,通过a本身或指针q,都可以修改a的值。这下p这个指向const变量的指针就彻底变成了个废物。

2

int * const p = new int;
int * q = p;

    2是一种正确的使用方法,虽然p是一个const指针,但是该指针所指向的变量是可以改变的,因此非const指针q指向p,通过q来修改p所指向的值并无不妥。

3

A a;
const A &aa = a;

    3中,aa被定义成对常量的引用,因此,aa只能访问声明为const的成员函数,不能访问其他成员函数。

3const参数和返回值

    参数const通常用于参数为指针或引用的情况。一般,如果函数的形参是指针或引用,我们可以在函数体内对指针指向的对象或引用的对象进行修改。因此,如果参数作输出用,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加const修饰,否则该参数将失去输出功能。

    如果参数不作输出用,则可以用const修饰参数。对于const参数,在函数体中按照const所修饰的部分进行常量化,如形参为const A* a,则不能对传递进来的指针的内容进行改变;如形参为const A& a,则不能对传递进来的引用对象进行改变。

    林博士在《高质量C++/C编程指南》中给我们的建议:对于非内部数据类型(例如用户自定义的类)的输入参数,应该将“值传递”的方式改为“const引用传递”,目的是提高效率;对于内部数据类型(int,short,long,char等等)的输入参数,不要将“值传递”的方式改为“const引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。

    对于const的函数返回值,通常用于二目操作符重载函数并产生新对象时,起相应的保护作用。例如:

const Rational operator*(const Rational& lhs, const Rational& rhs)
{
    
return Rational(lhs.numerator() * rhs.numerator(),
                            lhs.denominator() 
* rhs.denominator());
}

    const返回值可以防止下面的操作发生:

Rational a,b;
Radional c;
(a
*b) = c;
    但是通常不建议将返回值设定为const。因为如果返回值为某个const对象或const引用,则返回的实例只能访问类的public数据成员和const的成员函数,这样生成的新的对象似乎没有什么作用。

    再看看例4

const A& operator=(const A& a);

    如果连续赋值,就会出现问题:

A a,b,c;
(a
=b)=c;

    因为a.operator=(b)的返回值是对aconst引用,不能再将c赋值给const常量。


4
const成员函数

    任何不会修改数据成员的函数都应该声明为const类型。如果在编写const成员函数时,不慎修改了数据成员,或者调用了其它非const成员函数,编译器将指出错误,这无疑会提高程序的健壮性。

抱歉!评论已关闭.