C++_Const

来源:互联网 发布:增值税发票软件app 编辑:程序博客网 时间:2024/05/22 13:40
const的作用:表示被修饰变量受到强制保护,可以预防意外的变动,能提高程序的健壮性。

const的用处:修饰函数的参数、返回值、函数的定义体,变量等,其中前面三个是其魅力所在。

1、用const 修饰函数的参数

注意:如果在函数体中只是对参数读取数据,而不对参数进行修改,则该参数要使用const修饰。

什么时候使用const:

对于非内部数据类型的参数而言,传递参数常常使用引用传递+ const修饰

举例:
[cpp] view plaincopyprint?
void Func(const A &a)

原因:不加引用:传参时使用采用值传递而会产生A 类型的临时对象,而临时对象的构造、复制、析构过程都将消耗时间,效率比较底。而使用引用则就不会产生临时变量,而是原对象的一个别名,可直接使用

不加const:引用传递有可能改变参数a,这是我们不期望的。解决这个问题很容易,加const修饰即可。

对于内部数据类型的输入参数而言:不要将值传递的方式改为const 引用传递。

举例:
[cpp] view plaincopyprint?
void Func(int x) 不应该改为 void Func(const int &x)

原因:因为内部数据类型的参数不存在构造、析构的过程,而复制也非常快,“值传递”和“引用传递”的效率几乎相当,没有必要使用引用传递。否则既达不到提高效率的目的,又降低了函数的可理解性

2、用const 修饰函数的返回值:使函数返回值不会被改变

什么时候使用const:

1)函数返回值采用值传递,不要使用const修饰。

原因:函数返回值采用值传递方式,由于函数会把返回值复制到外部临时的存储单元中,这时const修饰的是临时变量,是不会得到改变,没有任何价值

举例:
[cpp] view plaincopyprint?
内部类型:不要把函数int GetInt(void) 写成const int GetInt(void)
不要把函数A GetA(void) 写成const A GetA(void),A为用户自定义类型

2)函数返回值采用指针传递方式,那么函数返回值(即指针)的内容不能被修改,并且该返回值只能被赋给加const修饰的同类型指针。

情况一:
[cpp] view plaincopyprint?
函数声明:const int* a()
函数调用:const int *p = a();
函数说明:我们可以把a()看作成一个变量,即指针指向内容不可变。

情况二:
[cpp] view plaincopyprint?
函数声明:int* const b()
函数调用:int * const p = b();
函数说明:我们可以把fun2()看作成一个变量,即指针变量本身内容不可变。

3)函数返回值采用引用传递方式的函数返回值加const修饰,那么该返回值的内容不能被修改。

注意:是不是接受值的变量可以不是与返回值相同类型的变量呢??

这点没有搞懂,因为我可以使用 一个不与返回类型相同的变量 接收,很困惑。

代码:返回值为一个const对象,但是可以使用一个非const对象接收
[cpp] view plaincopyprint?
#include <iostream>
using namespace std;
class MyClass
{
public:
int m_nTemp;
void fun1() const
{
}
void fun2()
{
}
const MyClass& fun6(MyClass& aa)
{
return aa;
}
};

void main()
{
MyClass aa;
MyClass bb;
bb=aa.fun6(aa);//运行正确,但是不正确啊,返回值不是只能是返回给一个const对象吗?
bb.fun1(); //可正确运行
bb.fun2(); //可正确运行---但是,按原理是不正确的,不懂。
bb.m_nTemp=22;//可正确运行---不懂
system("pause");
}

返回值为内部类型,但是可以使用一个非const内部类型接收
[cpp] view plaincopyprint?
#include <iostream>
using namespace std;
const int& ab(int a, int b,int& result)
{
result = a + b;
return result;
}
int main() {
int a = 1;
int b = 2;
int z;
// ab(a, b,z)++;//错误,表示返回的值为const,不可以进行修改,这个可以理解
int t = ab(a,b,z);//可以运行,使用一个非const接受,不是违背了 使用同类型返回值接受的语法了吗?
t++;//可以运行
cout << "t= " <<t<< endl;
system("PAUSE");
return 0;
}

自己总结下是不是这样,期待高手解答...

我们使用const修饰函数返回值时,应该主动使用一个对应的const对象来接收函数返回值,这样使用const修饰函数返回值才有意义。(能为const对象赋值)

当然关于报错的问题,如果使用返回指针,接受的类型和函数返回类型不搭配的话,会自动报错。

如果是返回一个类,接受类型和函数返回类型不配,竟然不报错,郁闷。

修改后的代码:定义一个类类型const变量,使用const修饰返回值函数可以初始化一个const类型的变量:
[cpp] view plaincopyprint?
#include <iostream>
using namespace std;
class MyClass
{
public:
int m_nTemp;
void fun1() const
{
}
void fun2()
{
}
const MyClass& fun6(MyClass& aa)
{
return aa;
}
};

void main()
{
MyClass aa;
const MyClass bb=aa.fun6(aa);//能使用返回const对象的函数为const对象赋值
bb.fun1();
// bb.fun2(); //报错,因为bb为const对象,只能调用const函数
// bb.m_nTemp=22; //报错
system("pause");
}

定义一个内部类型的const变量,使用const修饰返回值函数可以初始化一个const类型的变量
[cpp] view plaincopyprint?
#include <iostream>
using namespace std;
const int& ab(int a, int b,int& result)
{
result = a + b;
return result;
}
int main()
{
int a = 1;
int b = 2;
int z;
// ab(a, b,z)++;//错误,表示返回的值为const,不可以进行修改,这个可以理解
const int t = ab(a,b,z);//可以运行,使用一个非const接受,不是违背了 使用同类型返回值接受的语法了吗?
t++; //错误,不可以修改
cout << "t= " <<t<< endl;
system("PAUSE");
return 0;
}



说明:

1、const的优点,与预定义相比

预处理语句#define的缺点:预处理语句仅仅只是简单值替代,缺乏类型的检测机制。这样预处理语句就不能享受C++严格类型检查的好处,从而可能成为引发一系列错误的

隐患。 则Const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。

const的优点:

1)以const 修饰的常量值,具有不可变性,这是它能取代预定义语句的基础。

2)可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。

3)C++的编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高,同时,这也是它取代预定义语句的重要基础。

4)const定义也像一个普通的变量定义一样,它会由编译器对它进行类型的检测,消除了预定义语句的隐患。

2、指针和const连用:const修饰的是它右边的内容

1)
[cpp] view plaincopyprint?
char* const pContent;
表示:指针本身内容是常量,不可变
说明:const修饰pContent,表示变量的内容不变,即指针指向不变

2)
[cpp] view plaincopyprint?
const char* pContent;
表示:指针所指向的内容是常量不可变
说明:const修饰char*,表示指针指向的内容不变,即指针指向内容不变

3)
[cpp] view plaincopyprint?
const char* const pContent;
表示:两者都不可变
说明:pContent指向不变,指向的内容也不变