文章目录
简介
最近在阅读<Effective C++>这本书,阅读到条款三:尽可能的使用cosnt发现有好多遗忘的点,故写一篇文章来总结有关C++的 cosnt
什么是const呢?
const关键字用于定义一个常量,表示该对象是不能被修改的,是只读变量。
const 的使用
1.用来定义常量
- 在定义的时候需要进行初始化
const int x = 1; // x用const修饰后只读
x = 2; //error
2.和指针相关的const
- 指针所指向的内容不可以修改,如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量
const char c = 'x';
char const *p = &c; //这里表示c是不可以修改的
const char* p = &c; //这里表示c是不可以修改的
- 指针本身不可以修改,如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量
char a = 'y';
char c = 'x';
char* const p = &c; //这里表示p是不可以修改的
p = &y ; //error
*p = 1 ; //可以的
3.函数与const
- const修饰函数返回值
const int* f(); //int* 所指向的内容是不可以修改
int * const f(); //指针本身不可以修改
- const修饰函数的参数
//这里是值传递,产生的临时指针指向的内容不可以修改
void f(const int* a)
//引用的内容不可以修改
void f(const int& a)
4.类中使用const(重点)
const成员函数,在函数访问方面,只能访问const函数,不能访问非const函数
const成员函数,在变量访问方面,可以访问const和非const变量;
非const成员函数,可以访问const和非const的成员函数和变量;
const 对象只能操作const成员函数,不能操作非成员函数;
const对象可以访问const和非const变量
c++中去掉const属性
用const_cast<new_type>(expression)
new_type是转化之后的类型 expression是被转化的表达式
验证不同对象的调用
#include<iostream>
#include<vector>
using namespace std;
class test
{
public:
void f1();
void f2()const;
};
int main()
{
test t1;
const test t2;
//t1都能调用成功
//非const对象能调用const和非const成员函数
t1.f2();
t1.f2();
t2.f1(); //const对象调用非const成员函数错误
const_cast<test&>(t2).f1(); //把const属性去掉
t2.f2();
}
const修饰类内成员
- const成员只在某个对象生存期内是常量,而对于整个类而言却是可变的,因为类可以创建多个对象,不同的对象其const成员的值可以不同。所以不能在类声明中初始化const成员,因为类的对象未被创建时,编译器不知道const 成员的值是什么
- const数据成员的初始化只能在类的构造函数的初始化表中进行。要想建立在整个类中都恒定的常量,应该用类中的enum常量来实现(enum back)。
class test
{
const int x = 100; //这是错误的
};
class test1
{
enum { x = 10 }; //enum back
}
c++中的const 和 c中的const 的区别
c中的const
#include <stdio.h>
int main()
{
const int a = 1;
int *p = (int *)&a;
printf("1: %d\n", a); //1
*p = 10;
printf("2: %d\n", a); //10 可以发现a被修改成10了
}
为什么用指针能修改const常量的值呢?
其实const修饰的局部变量是在栈上分配空间,所以可以用指针修改该空间的值而修改该const局部变量的值
为什么c++中的const常量又不能通过指针修改呢
定义时,变量并不开辟内存空间,不会存储在内存中,而是开辟一张表,以key-value的形式存储,当const变量进行普通使用的时候,直接去表里面进行查表,拷贝过来用,当有取地址操作(&包含引用)或者extern操作(跨cpp文件使用)的时候,会开辟一片内存空间,从表中将值复制过来,存储在该内存空间,所以无论普通使用,还是通过取地址等操作,值都没有变,都来源那个表
const 和 #define
const和define都能作为常量来使用
区别
- const有作用域的概念,函数内部定义的const变量只能在函数内部使用;而define没有作用域的概念(除非使用ifdef配合)一个函数内定义的宏定义变量可以在另外一个函数中使用
- const变量的处理时机是编译器,所以会有作用域等检查,define是由预处理器处理,是单纯的文本替换
- define不能用来定义class专属常量,没有任何封装性
const总结
- 我们应当尽可能的使用const,减少#define的使用
- 任何不会修改数据的成员函数都应该声明为const 类型:void fun() const;
- 函数的返回值为某个对象时,如果将其声明为const时,多用于操作符的重载