(1)const 在c 和 c++ 中的区别?
在c语言中,const 的意思是:一个不能被改变的普通变量,总是占用内存,c编译器不能把const 视为一个编译期间的常量
const int buffersize = 10;
int buf[buffersize];
这种写法在c 中是错误的,因为编译器不知道它在编译时的值
但是这种写法在c++中却是成立的
在C语言中,const int i,j=0; 这种写法是正确的,因为c编译器把它作为一个声明,这个声明表示在别的地方有存储分配,但是在c++中,这种写法是错误的,在c++中,i,j 相当于常量,常量在定义之后就不能被修改,所以在定义时就必须进行初始化,如果想要在c++中用 const int i 可以在它前面加上extern
c默认是外部连接,c++默认是内部连接
(2)用const 代替#define 的作用
a.const 常量有数据类型,而宏常量没有数据类型
b.编译器会对const 进行类型安全检查,宏常量只进行简单的字符替换,还有意想不到的边际效应
c.使用const 常量可以比#define 产生更小的目标代码
d.使用const 可以执行常量折叠,把常量表达式计算求值,并用所求的值来替换表达式
(3)const 和指针
指向const 对象的指针------------》指针所指的对象的值不能被改变,指针的指向可以改变
const 指针---------------------------》指针的指向不能改变,但是所指的对象的值可以改变
double * const ptr = &d;
ptr 是一个指向double 类型的const 指针,指针的指向不能改变,但是指针所指的值是可以改变的
double *ptr = &value
ptr 是一个指向double 类型的指针,ptr 的指向可以改变,ptr 所指的value值也可以改变
const double *ptr = &value
ptr 是一个指向const double 类型的指针,ptr 的指向可以改变,但是ptr所指的值不能改变
(4)const 可以修饰函数返回值,参数
a.修饰返回值
char * GetMemory(void)
{
char *p = "hello";
return p;
}
char *str = GetMemory();
str[0] = 'a';========>对常量字符串进行修改,会导致程序崩溃,编译时不会指出错误,但是如果声明为const ,编译时就会指出错误。
b.修饰参数=======》在函数体内不会对参数修改
int fun(int *i);=======>int *i
const int a = 1;=====>const int
fun(&a)======>类型不兼容
int fun(const int *i)====>
int a;========>可以接受
const int a======>可以接受
在函数参数中使用常量引用非常重要,因为函数可能会接受临时的对象
void f(int &i)======》必须改为void f(const int &i)
f(1) ==>编译器必须先建立一个引用,编译器为一个int 型分配临时存储单元,同时将其初始化为1并为其产生一个地址和引用捆绑在一起,存储的内容是常量,所以实参是const int 型
(5)const 在类中的使用
a.const 成员函数
class base
{
void func1();
void func2()const;
};
常量成员函数=====》改变的隐含的this 形参的类型,使this 形参指向的对象为const类型,this 本身的类型为base *const ,函数声明末尾加上const 后,this 的类型为 const base * const ;
为成员函数引入const 目的:确保该成员函数可用于const 对象上,const 对象,指向const 对象的指针或者引用只能调用其const 成员函数
const 对象====只能===》const 成员函数
const 对象====不能===》非const 成员函数
b.const 数据成员
1》const 数据成员必须在构造函数的成员初始化列表中进行初始化
2》static 静态成员变量不能在类的内部初始化,定义必须在类的外部进行定义,static 关键字只能出现在类声明中,定义时不能标识为static
3》const 成员变量也不能在类的内部初始化,只能通过构造函数的初始化表进行,并且必须有构造函数,const 数据成员只在某个对象的生存期内是常量,而对于整个类而言,却是可变的,因为一个类可以创建多个对象,不同的对象,其const 数据成员的值不同,所以不能在类的声明中初始化const 数据成员的功能,因为没有创建类的对象时,编译器不知道const 数据成员的值是什么
如果想要建立在整个类中都恒定的常量,可以在类中用枚举常量来表示或者 static const
class Test
{
public:
Test():a(){}
enum{size1=100,size2 = 200};
private:
const int a; 只能在构造函数初始化列表中进行初始化
static int b; 在类的实现文件中定义并初始化
const static int c; 与static const int c 相同,c为整型,所以可以在这里进行初始化,但是仍需要在类外定义,但是c 为非整型时,不能在此处进行初始化
};
int Test::b=0; static 不能在构造函数初始化列表中初始化,因为它不属于某个对象,它是与类直接关联
const int Test::c=0; 给static const 赋值时,不需要加static 修饰符,但必须要加const