const基础用法
来源:互联网 发布:淘宝有没有货到付款的 编辑:程序博客网 时间:2024/04/28 09:40
一 const基础 如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量; 如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。 因此,[1]和[2]的情况相同,都是指针所指向的内容为常量(const放在变量声明符的位置无关),这种情况下不允许对内容进行更改操作,如不能*a = 3 ; [3]为指针本身是常量,而指针所指向的内容不是常量,这种情况下不能对指针本身进行更改操作,如a++是错误的; [4]为指针本身和指向的内容均为常量。 二 作为参数 void display(const double& r);或者void display(const double* r); 说明: 1 在引用或者指针参数的时候使用const限制是有意义的,而对于值传递的参数使用const则没有意义 2 保证引用的变量的值不被改变 3 const在double前或者后面意思相同,只是不同的人的写法不同 三 const对象 声明为const的对象只能访问类中声明为const的成员函数,不能调用其它成员函数. 四 const成员函数 类型说明符 函数名(参数表)const; void print(int i) const; 说明: 1 const是函数类型的一个组成部分,因此在实现部分也要带const关键字. 2 常成员函数不能更新对象的数据成员,也不能调用该类中没有用const修饰的成员函数. ================================================
如果const关键字不涉及到指针,我们很好理解,下面是涉及到指针的情况:
int b = 500;
const int* a = &b; [1]
int const *a = &b; [2]
int* const a = &b; [3]
const int* const a = &b; [4]
如果你能区分出上述四种情况,那么,恭喜你,你已经迈出了可喜的一步。不知道,也没关系,我们可以参考《Effective c++》Item21上的做法,
五 使用const的一些建议
1 要大胆的使用const,这将给你带来无尽的益处,但前提是你必须搞清楚原委;
2 要避免最一般的赋值操作错误,如将const变量赋值,具体可见思考题;
3 在参数中使用const应该使用引用或指针,而不是一般的对象实例,原因同上;
4 const在成员函数中的三种用法(参数、返回值、函数)要很好的使用;
5 不要轻易的将函数的返回值类型定为const;
6除了重载操作符外一般不要将返回值类型定为对某个对象的const引用;
1.使用const的好处
1.1在<<C++编程规范>>中的说法是“尽量使用const来代替#define”. 如果你使用下面的语句定义一个宏(宏:文字替换而已)
#define MAX_LENGTH 100
MAX_LENGTH这个名字就只能被编译器的预处理程序所看到,程序中所有出现MAX_LENGTH的地方都被预处理程序替换为100,此后编译器看到的只是100这个常数。当宏较大较复杂且有错时,编译器报出的错误可能是难以理解的。这时如果我们用
const int MAX_LENGTH = 100;
编译器就可以看到MAX_LENGTH这个符号,并且可以对MAX_LENGTH进行类型检查,在代码发生错误时也能正确地报出错误位置。
1.2在团队开发中有用,比如你写一个函数计算字符串的长度,原型写成int MyStrLen(const char * str),则表示这个函数并不会改变str所指向的内容(即*str).这样使用起来更加安全,该const限制能保证团队的开发人员按正确的方式使用已有代码。
2.使用const来标识常量
这个是笔试喜欢考的东东,考改错的可能性比较大,或者问答题(偶上次TrendMicro考的是改错题,偶做得还不错)
//整型常量,以后不能再对它赋值,因此必需赋一个初值
int const number = 1;
//同上,可见const 放在int 前面或后面的意义是一样的
const int number = 1;
//指向常量的变量指针,*p不可变,p可变(可指向别处)
int const *p;
//同上,可见const 放在int 前面或后面的意义是一样的
const int *p;
//指向变量的常量指针,p不可变,但p指向的内容number1可变,p以后不能改变,所以必须赋初值
int* const p = &number1;
//指向常量的常量指针,p不可变,number也不可变,p以后不能改变,所以必须赋初值
const int * const p = &number;
//引用,C++引用都是常量引用,引用的指向不可变,一个引用指向一个变量后就不能再改变它使它指向另一个变量(因此必
//须赋初值),当然引用所指向的内容可以改变(人家指向的是变量嘛),引用一般是出现在函数的参数中
int & number2 = number;
这个其实很容易记的,主要是看const修饰的是谁
3.修饰类的常量成员
如果一个常量只会在一个类里使用,那么我们就不应该把它定义为全局常量,我们应该把我定义在类的内部
class Example
{
public:
const int MAX_LENGTH = 100;
};
上述代码虽然能通过编译,但存在一下悖论,MAX_LENGTH既然是一个常量,那么它一定不会改变,按照上面的代码,类的每一个对象(也称实例)中都会有一份MAX_LENGTH的COPY,这不是在白白浪费内存?所以通常类中的常量应当定义为一个静态变量,标准的代码如下
class Example
{
public:
static const int MAX_LENGTH;//static 的常量不能在类中定义,要移到外面去
};
const int Example::MAX_LENGTH = 100;//static 的常量不能在类中定义
4.修饰函数的参数
大家都知道C++中函数的参数是按值传递的,当我们要传入一个大型对象的时候,使用按值传递就很不实惠,因为按值传递会生成该对象的一个COPY.浪费呀!!因此在传递对象的时候最好使用指针或引用.
但是在一般情况下,我们并不希望函数改变我们所传入的参数,而使用指针或引用做参数就存在被修改的可能性.
因此对于不应当被修改的东东我们应当使用const来修饰之
比如写一个字符串COPY的函数
bool CopyString(MyString& szDest,const MyString& szSrc);//假设MyString是我自己定义的一个字符串类
上面的函数表明,源字符串szSrc不会(也不应当)被CopyString函数修改,而目标字符串szDest当然要改变了.
5.修饰类的成员函数
先写一个不用const修饰成员函数的类
class MyString//我的字符串类(仅仅用于教学,没有什么实际的意义)
{
//......
private:
int len;
public:
int GetLength();//获得串的长度
void SetLength(int len);//设置长度
//......
};
///GetLength的实现
int MyString::GetLength()
{
return this->len;
}
///SetLength的实现
void MyString::SetLength(int len)
{
this->len = len;
}
类的成员函数(内联除外)是另外安排空间的,并不放在类的里面,类的各个对象调用的都是外部的同一个函数.如:
MyString s1;
MyString s2;
s1.SetLength(1);
s2.SetLength(2);
s1与s2调用的是同一份函数体,那SetLength(...)如何区分来自于不同的对象的调用呢?参考<<深度探索C++对象模型>>可知道
其实GetLength函数的原型并不是GetLength( ),而是GetLength(MyString * const this),当s1调用GetLength时其实是调用GetLength(s1),这里用const 来修饰this说明this是一个不可变的指针,你不能在GetLength函数里把它指向别处,当然你可以改变this所指向的内容.
使用const修饰类的成员函数(就是在括号后加上一个const,形如:int GetLength()const;),编译器会为我们生成以下函数
GetLength(MyString const * const this)
由该原型可以看出,const修饰成员函数的作用在于:表明该成员函数不会修改*this内容,比如GetLength的职责只是返回字符串的长度,而不是修改对象中的任何数据.
下面说说作用(也就是笔试考点) PS:前几天趋势公司考过,怕大家以后笔试遇到,于是就帖出来了
bool CopyString(MyString & szDest,const MyString & szStr)
{
//......
szDest.SetLength(szStr.GetLength());//假设我们就只做这件无聊的事
//......
}
如果GetLength不是const型,则不能编译通过,解释如下
CopyString的第二个参数 const MyString & szStr表明szStr是一个const引用,当szStr.GetLength()时传递给GetLength的第一个参数是szStr 的类型是MyString const *const szStr,
而未经const修饰的GetLength接受的第一个参数是MyString * const this,两者不匹配编译出错
如果用const修饰GetLength则GetLength的第一个参数是MyString const * const this 与szStr匹配,编译通过
- const基础用法
- const 关键字基础用法
- C语言基础-const用法
- const用法
- const用法
- const用法
- const用法
- const用法
- const 用法
- const用法
- const 用法
- const用法
- const用法
- const用法
- const用法
- const用法
- const用法
- CONST用法
- Bootloader U-boot启动
- 神奇:保宁醋厂区50年无人患传染性疾病(真的假的啊)
- 网页文本加title显示图片特效
- KML->SHP
- 任务计划
- const基础用法
- Oracle与SQL Server的互连
- BCB没有Indy或Help的解决办法
- Enterprise Library 4.1数据访问应用程序块快速入门【1】使用DbDataReader检索多行
- CopyU!更新
- GNU make 的主要预定义变量
- PHP 图片添加水印(文字和图片)
- 配置ASP.NET平台时遇到的“访问IIS元数据库失败”
- OWASP-IG-002