c++中的const参数,const变量,const指针,const对象,以及const成员函数

const 是constant 的缩写,“恒定不变”的意思。被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。所以很多C++程序设计书籍建议:“Use const whenever you need”。

1.用const 修饰函数的参数

如果参数作输出用,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加const 修饰,否则该参数将失去输出功能。const 只能修饰输入参数:

如果输入参数采用“指针传递”,那么加const 修饰可以防止意外地改动该指针,起到保护作用。

例如StringCopy 函数:

void StringCopy(char *strDestination, const char *strSource);

其中strSource 是输入参数,strDestination 是输出参数。给strSource 加上const修饰后,如果函数体内的语句试图改动strSource 的内容,编译器将指出错误。

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

例如不要将函数void Func1(int x) 写成void Func1(const int x)。同理不要将函数void Func2(A a) 写成void Func2(const A a)。其中A 为用户自定义的数据类型。

对于非内部数据类型的参数而言,象void Func(A a) 这样声明的函数注定效率比较底。因为函数体内将产生A 类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。

为了提高效率,可以将函数声明改为void Func(A &a),因为“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。但是函数void Func(A & a) 存在一个缺点:

“引用传递”有可能改变参数a,这是我们不期望的。解决这个问题很容易,加const修饰即可,因此函数最终成为void Func(const A &a)。

以此类推,是否应将void Func(int x) 改写为void Func(const int &x),以便提高效率?完全没有必要,因为内部数据类型的参数不存在构造、析构的过程,而复制也非常快,“值传递”和“引用传递”的效率几乎相当。

问题是如此的缠绵,我只好将“const &”修饰输入参数的用法总结一下。

对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const 引用传递”,目的是提高效率。例如将void Func(A a) 改为void Func(const A &a)。

对于内部数据类型的输入参数,不要将“值传递”的方式改为“const 引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(const int &x)。

2 .用const 修饰函数的返回值
如果给以“指针传递”方式的函数返回值加const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。例如函数
const char * GetString(void); 
如下语句将出现编译错误:
char *str = GetString(); 
正确的用法是
const char *str = GetString(); 
如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const 修饰没有任何价值。
例如不要把函数int GetInt(void) 写成const int GetInt(void)。
同理不要把函数A GetA(void) 写成const A GetA(void),其中A 为用户自定义的数据类型。
如果返回值不是内部数据类型,将函数A GetA(void) 改写为const A & GetA(void)的确能提高效率。但此时千万千万要小心,一定要搞清楚函数究竟是想返回一个对象的“拷贝”还是仅返回“别名”就可以了,否则程序会出错。
函数返回值采用“引用传递”的场合并不多,这种方式一般只出现在类的赋值函数中,目的是为了实现链式表达。

例如:

 1 class A
 2 {
 3     A & operate = (const A & other); // 赋值函数
 4 } ;
 5
 6 A a, b, c; // a, b, c 为A 的对象
 7
 8 a = b = c; // 正常的链式赋值
 9
10 (a = b) = c; // 不正常的链式赋值,但合法

如果将赋值函数的返回值加const 修饰,那么该返回值的内容不允许被改动。上例中,语句 a = b = c 仍然正确,但是语句 (a = b) = c 则是非法的。

3. const 成员函数
任何不会修改数据成员(即函数中的变量)的函数都应该声明为const 类型。如果在编写const 成员函数时,不慎修改了数据成员,或者调用了其它非const 成员函数,编译器将指出错误,这无疑会提高程序的健壮性。以下程序中,类stack 的成员函数GetCount 仅用于计数,从逻辑上讲GetCount 应当为const 函数。编译器将指出GetCount 函数中的错误。

 1 class Stack
 2 {
 3     public:
 4     void Push(int elem);
 5     int Pop(void);
 6     int GetCount(void) const; // const 成员函数
 7     private:
 8     int m_num;
 9     int m_data[100];
10 } ;
11
12 int Stack::GetCount(void) const
13 {
14     ++ m_num; // 编译错误,企图修改数据成员m_num
15     Pop(); // 编译错误,企图调用非const 函数
16     return m_num;
17 } 

const 成员函数的声明看起来怪怪的:const 关键字只能放在函数声明的尾部,大概是因为其它地方都已经被占用了。
关于Const函数的几点规则:
a. const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数.
b. const对象的成员是不可修改的,然而const对象通过指针维护的对象却是可以修改的.
c. const成员函数不可以修改对象的数据,不管对象是否具有const性质.它在编译时,以是否修改成员数据为依据,进行检查.
e. 然而加上mutable修饰符的数据成员,对于任何情况下通过任何手段都可修改,自然此时的const成员函数是可以修改它的

时间: 2024-08-06 03:47:02

c++中的const参数,const变量,const指针,const对象,以及const成员函数的相关文章

【03】指针、返回值、成员函数的const

1 // 2 // 2015-03-05 03/55 3 // 指针.返回值.成员函数 之 const 4 // 5 6 #include <iostream> 7 #include <string> 8 9 using namespace std; 10 11 // ------------------------------ 12 // 1. 指针的const 13 // ------------------------------ 14 const char *p1 = &q

理解ATL中的一些汇编代码(通过Thunk技术来调用类成员函数)

我们知道ATL(活动模板库)是一套很小巧高效的COM开发库,它本身的核心文件其实没几个,COM相关的(主要是atlbase.h, atlcom.h),另外还有一个窗口相关的(atlwin.h), 所以拿来学习应该是很方便的.但是因为ATL的代码充满了模板和宏,内部还夹杂着汇编,所以如果没有比较丰富的C++模板和系统底层的知识,一般人会看得一头雾水. 下面我们主要分析一下ATL中的一些汇编代码. ATL中出现汇编代码主要是2处,一处是通过Thunk技术来调用类成员函数处理消息:还有一处是通过打开_

C++中的const成员函数

数据成员的值反应了对象在程序运行某个时刻的状态.数据成员值的改变是由于对象处理了一条消息,往往是某个成员函数被调用.但是有的时候我们希望,成员函数仅仅是访问数据成员而不对其值进行修改.所以,对象的成员函数被分成了两类: 1. 修改对象状态的成员函数: 2. 获取对象状态的成员函数: 而const 成员函数就是为第2个功能而设计.尽管,只要我们在成员函数里不修改对象数据成员的值就可以认为这是一个获取对象状态 的成员函数,但是有的时候在实现的时候会无意的改变数据成员的值,所以为了起到防范的目的,C+

C++中基于成员函数是否是const重载成员函数

C++pimer中文版第四版 378页 基于const的重载 如果我们要在一个类的成员函数中定义两个函数签名完全一样的成员函数,比如display,那么可以基于是否是const成员函数来重载.比如: //非const对象可以使用可以使用任意成员,但是下面这个匹配的更好,所以一般用这个成员函数 Screen& display(ostream& os){ os << "something"; return *this;//返回的是普通引用 Screen&

C++ const成员函数

预备知识 1.代码转换分析技巧 在早期某些编译器会将C++代码翻译为C代码,然后使用C编译器生成可执行文件.其中翻译的一个转化就是:将this指针显式添加到成员函数的第一个参数位置上,因为C中没有OOP的支持,并在成员函数调用时,自动将对象的地址传递给参数this. 这个过程用如下代码解释: #include<iostream> #include<cstdio> using namespace std; class Dog { public: Dog(unsigned en = 0

C++类const成员函数

c++类中可以用const关键字来声明不修改对象的成员函数,它使用时需要注意: 1.常量对象只能调用const成员函数 2.非常量对象可以调用const成员函数 以下列代码为例,来解释: 1 class Person{ 2 public: 3 void print(){ 4 cout<<"I am a common function!"<<endl; 5 } 6 void show()const{ 7 cout<<"I am a const

类 this指针 const成员函数

C++ Primer 第07章 类 7.1.2 ?Sales_data类的定义如下: #ifndef SALES_DATA_H #define SALES_DATA_H #include <string> #include <iostream> class Sales_data { public: std::string isbn() const {return bookNo;} Sales_data& combine(const Sales_data&); dou

类 this指针 const成员函数 std::string isbn() const {return bookNo;}

转载:http://www.cnblogs.com/little-sjq/p/9fed5450f45316cf35f4b1c17f2f6361.html C++ Primer 第07章 类 7.1.2 ?Sales_data类的定义如下: #ifndef SALES_DATA_H #define SALES_DATA_H #include <string> #include <iostream> class Sales_data { public: std::string isbn

const成员函数总结

const 成员函数: 类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变. 在设计类的时候,一个原则就是对于不改变数据成员的成员函数都要在后面加 const,而对于改变数据成员的成员函数不能加 const. 所以 const 关键字对成员函数的行为作了更加明确的限定:有 const 修饰的成员函数(指 const 放在函数参数表的后面,而不是在函数前面或者参数表内),只能读取数据成员,不能改变数据成员:没有 const 修饰的成员函数,

python--005-函数参数、变量

·函数的参数··参数1.形式参数:parameter--形式参数创建函数时,小括号内的参数2.实际参数:argument--实参函数调用时,小括号内传递进去的参数 ··函数文档1.直接书写字符串2.用#标记单行的注释3.可以用print('内容')直接输出内容 #-- coding: utf-8 --#这个函数求两个数值之和def add(num1,num2):'把num1和num2 的和进行返回'#这行字符串是一个注释print ('求两个值的和')return num1+num2 print