C++ const

 也可参考http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777416.html

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

 

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

 

 

1).C++中的const

    C语言和C++中的const有很大区别。在C语言中用const修饰的变量仍然是一个变量;而在C++中用const修饰过后,就变成常量了。

   如:

const int n=5;
int a[n];

这种方式在C语言中会报错,原因在于声明数组时数组的长度必须为一个constant,即常量,虽然n用const限定了,但n终究是一个变量,因此会报错;

但是在C++中不会报错,因为在C++中用const修饰过后,n就已经等同于一个常量了,因此可以通过。

又如:

复制代码
复制代码
#include<iostream>
using namespace std;

int main(void)
{
const int a=3;
//int* pa=&a;// segment fault
int* pa=(int*)&a;
*pa=4;
printf("%d\n",*pa);
printf("%d\n",a);
return 0;
}

编译结果:
e:\c++\acm\lianxi.cpp(7) : error C2440: 'initializing' : cannot convert from 'const int *' to 'int *'
复制代码
复制代码

这种情况在C++中是不允许的,原因在于a用const修饰后,已经成为常量了,因此是不允许被修改的,无论是显式的更改a的值或是通过其它方法修改它的值都是不允许的。

 

 

常引用

 

引用前面可以加const关键字,成为常引用。不能通过常引用,修改其引用的变量。

const int & r = n;
r = 5; //error
n = 4; //ok

 

2).const修饰函数参数

 

  传递过来的参数在函数内不可以改变,与上面修饰变量时的性质一样。

 

void testModifyConst(const int _x) {
     _x=5;   ///编译出错
}

 

3).const修饰成员函数

 const 修饰符能修饰类的成员函数而不能修饰普通的自定义函数(后半句有待考证),类的成员函数加上了const修饰符后它用两个作用,1:在该函数内不允许对类的私有数据成员进行 修改,2:当声明了一个const的该类对象时,该对象只能调用该类的const成员函数而不能调用非const成员函数.如果声明一个非const的该 类对象,该对象既可以调用const成员函数也可以调用非const成员函数.

(1)const修饰的成员函数不能修改任何的成员变量(mutable修饰的变量除外)

 

(2)const成员函数不能调用非onst成员函数,因为非const成员函数可以会修改成员变量

 

复制代码
复制代码
 1 #include <iostream>
 2 using namespace std;
 3 class Point{
 4     public :
 5     Point(int _x):x(_x){}
 6 
 7     void testConstFunction(int _x) const{
 8 
 9         ///错误,在const成员函数中,不能修改任何类成员变量
10         x=_x;
11 
12         ///错误,const成员函数不能调用非onst成员函数,因为非const成员函数可以会修改成员变量
13         modify_x(_x);
14     }
15 
16     void modify_x(int _x){
17         x=_x;
18     }
19 
20     int x;
21 };
复制代码
复制代码

 

 4).const修饰函数返回值

 

(1)指针传递

 

如果返回const data,non-const pointer,返回值也必须赋给const data,non-const pointer。因为指针指向的数据是常量不能修改。

 

复制代码
复制代码
 1 const int * mallocA(){  ///const data,non-const pointer
 2     int *a=new int(2);
 3     return a;
 4 }
 5 
 6 int main()
 7 {
 8     const int *a = mallocA();
 9     ///int *b = mallocA();  ///编译错误
10     return 0;
11 }
复制代码
复制代码

 

(2)值传递

 

 如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const 修饰没有任何价值。所以,对于值传递来说,加const没有太多意义。

 

所以:

 

  不要把函数int GetInt(void) 写成const int GetInt(void)。
  不要把函数A GetA(void) 写成const A GetA(void),其中A 为用户自定义的数据类型。

在编程中要尽可能多的使用const,这样可以获得编译器的帮助,以便写出健壮性的代码。

非静态成员函数后面加const(加到非成员函数静态成员后面会产生编译错误),表示成员函数隐含传入的this指针为 const指针,决定了在该成员函数中,任意修改它所在的类的成员的操作都是不允许的(因为隐含了对this指针的const引用);唯一的例外是对于 mutable修饰的成员。加了const的成员函数可以被非const对象和const对象调用,但不加const的成员函数只能被非const对象调 用(const对象不能调用非const的成员函数,)

对于const类对象/指针/引用,只能调用类的const成员函数。例如:
class A
{
private:
int m_a;
public:
A() : m_a(0) {}
int getA() const { return m_a; //同return this->m_a;}
int GetA() { return m_a; }
int setA(int a) const
{
m_a = a; //这里产生编译错误,如果把前面的成员定义int m_a;改为mutable int m_a;就可以编译通过。
}
int SetA(int a)
{ m_a = a; //同this->m_a = a;
}
};
A a1;
const A a2;
int t;
t = a1.getA();
t = a1.GetA();
t = a2.getA();
t = a2.GetA(); //a2是const对象,调用非const成员函数产生编译错误。

 

两个成员函数,名字和参数表都一样,但是一个是const,一个不是,算重载;

复制代码
class Point
{
private:
    int n;
public:
    Point(){n=1;}
    int GetValue()const {return n;}
    int GetValue(){return 2*n;}
};
int main()
{
    const Point p1;
    Point p2;
    cout<<p1.GetValue()<<" "<<p2.GetValue()<<endl;//1 2
    return 0;
}

//https://blog.csdn.net/fighting123678/article/details/79704193 
复制代码

 

posted @   PKICA  阅读(14)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示