关键字-const使用总结

1.const定义变量时初始化流程。

    分为运行时初始化和编译时初始化两种。

const int i = get_size();	//运行时初始化
const int j = 43;			//编译时初始化
2.为什么在默认情况下,const对象仅在本文件内有效?

     当以编译时初始化的方式定义一个const对象时,如下 
 

const int j = 43;			//编译时初始化,把代码中用到j的地方换成43
    编译器将在编译过程中把用 到该变量的地方都替换成对应的值,如果程序包含多个文件,则每个用了const 对象的文件都应可以访问到他的初始值。为了支持这个用法, 同时避免对同一变量的重复定义,默认情况下,const对象仅设定为仅在文件内有效。

    为了让const对象在多个文件均可共享,解决办法是,对于const 变量不管是声明还是定义都添加extern关键字。

//file_1.c定义并初始化了一个常量,该常量能被其他文件访问
extern const int bufSize = fnc();   //运行时初始化

//file_1.h头文件
extern const int bufSize; 	        //与bufSize是一个常量
3.常量与指针

int        a = 0;
const int *p = a;	//指向常量的指针
int* const p = &a;      //常量指针
 4.常量与引用

int   i = 43;
const int &r1 = i;      //正确,
const int &r2 = 42;     //正确,相当于产生了一个临时量将r2绑定到临时对象上,const int tmp = 42;const int &r2 = tmp;
const int &r2 = r1 * 2; //正确,同上
//注意:没有 int& const r2 = i;
  5. 常量与重载

     带常量参数的重载需要区分底层const和顶层const

//合法的,区别是他们的引用类型的形参是否引用了常量,属于底层const
int  calc(char, char);
int  calc(const char&, char const&);

//合法的,区别是他们的指针类型的形参是否指向了常量,属于底层const
int  calc(char, char);
int  calc(char const*, char const*);

//非法的重载:两个函数的区别是他们形参本身(指针类型)是否为常量
//属于顶层const,属于精确匹配范畴:向实参添加顶层const或者从实参中删除顶层const
int  calc(char a, char b);
int  calc(char* const, char* const);
  6.const与类

    1.定义隐式形参this定为常量

//默认情况下this为指向非常量版本的常量指针,若需要兼容常量版本,需要在函数声明后加入const
class Sales_data {
public:
	std::string isbn() const { return bookNo; }	
private:
	std::string bookNo;
};
    2.底层const在类中的重载

//基于const this的成员函数重载
class Screen {
public:
    Screen&       display(std::ostream &);
    const Screen& display(std::ostream &)const; //*this将返回常量引用
};
 7.去除const属性

    1.方法一:可以通过关键字mutable可变成员参数去const 类中的成员变量的常量属性

class People{
public:
	//即使const对象也能被修改
	int incAge()const 
	{ int last = age++; return last;} 
private:
	mutable int age = 1;
};
   2.方法二:通过const_cast强制消除const属性,一般用在 函数重载
const string &shorterString(const string &s1, const string &s2)
{
    return s1.size() <= s2.size() ? s1 : s2;
}

string &shorterString(string &s1, string &s2)
{
	//返回类型为const string&,
    auto &r = shorterString(const_cast<const string&>(s1), const_cast<const string&>(s2));
    return const_cast<string&>(r);	//r引用实际是绑定在非常量上,因此const_cast<string&>转化有效  
}
int main(int argc, char** argv) {
	
	string s("hello"); 
	string l("hello world");
	
	shorterString(s, l) += "!!!";
	cout << "s = " << s << endl;
	cout << "l = " << l << endl;
	return 0;
}

//输出结果 
s = hello!!!
l = hello world
   附:关于const_cast使用注意事项

 //const_cast使用注意:
   1.本身为常量但转化为非常量为未定义行为
   	const int a = 1;
	int *pa = const_cast<int*>(&a); //未定义行为
	
	int& b = const_cast<int&>(a);   //未定义行为
	++b;					 //对a无效
	cout<< a << b << endl;   //调试打印为1 2
	
	++(*pa);
	cout<< a << (*pa)<<endl; //调试打印为1 3
	
   2.只能转换底层const属性:
   	const int a = 1;
	int b = const_cast<int>(a);  //错误:const_cast只能改变底层const
     








 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值