const 用法总结
- 修饰普通变量
const int a = 10;
说明:
1)表明该值在初始化后不能被修改。
2)声明时必须初始化,否则编译报错。
- 修饰指针
1)指向常量的指针
const int a = 10;int b = 11;int c = 12;const int *p = &a;std::cout << *p << std::endl;//*p = 11;//报错,p 不能给常量赋值p = &b;//但是 p 可以指向新的地址std::cout << *p << std::endl;
说明:
1) const 在 * 的左边, const int *p 和 int const * p 含义一样。
2) 不能通过指针修改指向地址的内容。
3) 指针本身可以重新指向其他地址。
2)常量指针
const int a = 10;int b = 11;int c = 12;//int * const q = &a; //编译报错,无法从“const int *”转换为“int *,转换丢失限定符int * const q = &b;*q = 12;std::cout << "*q=" << *q << " b=" << b << std::endl;q = &c; //报错,q不能给常量赋值。 q 本身不能再指向其他地址
说明:
1) const 在 * 的右侧,常量指针不能指向常量变量的地址,编译报错。如上述:int * const q = &a
2) 声明时,必须初始化,且初始化后不能再指向其他地址,否则编译编译报错。如上述:q = &c
3) 可以通过指针修改指向地址的值。如上述:*q = 12
3)指向常量的常量指针
const int *const p = &a; // *p = 20; // 错误:内容不可修改 // p = &b; // 错误:指针不可修改
说明:
既不能修改指针指向的地址,也不能通过指针修改指向地址的值。
3. 修饰函数参数
void TestModify(const QString& name){qDebug() << "name=" << name;name = "newName"; //编译报错}
说明:
1) 当函数形参是按值传递的时候,使用 const 的意义不大。
2) 当函数形参是按引用传递或指针时,使用 const 修饰,可以防止函数内部对形参的修改。
4. 修饰函数返回值
const char *TestFun1() {return "Hello World"; // 字符串字面量是常量}int main(int argc, char *argv[]){//char* msg = TestFun1(); //编译报错,返回值必须赋值给一个常量 “初始化”: 无法从“const char *”转换为“char *”const char* msg1 = TestFun1();//msg1[1] = 'b';}
5.修饰成员函数
示例一:
class A{public:A() {}const void funA() const { qDebug() << "const test"; }void funcB() { qDebug() << " tt"; }};int main(int argc, char *argv[]){A a;a.funA(); //非 const 对象调用const成员函数a.funcB();//非 const 对象调用非 const 成员函数const A b;b.funA(); //const 对象调用 const 成员函数//b.funB(); //const 对象调用非 const 成员函数,编译报错。"funB": 不是 "A" 的成员}
示例二:
class Student{public:Student(const QString& name, int age){_name=name;_age = age;}QString Name() const{ return _name; }int Age() const { return _age;}void PrintSelf() const{qDebug() << "name=" << _name << "\tage=" << _age;}const Student& TopAge(const Student& stu) const{if(this->_age > stu.Age())return *this;elsereturn stu;}private:QString _name;int _age;};int main(int argc, char *argv[]){Student s("ella", 15);s.PrintSelf();const Student s1("lili", 10);s1.PrintSelf();Student top = s.TopAge(s1);top.PrintSelf();}
const Student& TopAge(const Student& stu) const
形参中的 const : 表明不会修改被显示访问的对象(s1)
括号后的 const : 表明不会修改被隐式访问的对象(s)
返回值的 const : 返回两个const对象之一,所以返回值也设置为 const
- 与 define 的区别
-
编译阶段:
- define是在编译预处理阶段进行简单的文本替换,
- const是在编译阶段确定其值
-
安全性:
- define定义的宏常量没有数据类型,只是进行简单的替换,不会进行类型安全检查;
- const定义的常量是有类型的,是要进行类型判断的
-
内存占用:
- define定义的宏常量,在程序中使用多少次就会进行多少次替换,内存中有多个备份,占用的是代码段的内存;
- const定义常量占用静态存储区域的空间,程序运行过程中只有一份
-
调试:
- define定义的宏常量不能调试,因为在预编译阶段就已经进行替换了;
- const定义的常量是可以进行调试的。