C++:const ,帮你理解所有有关const的一切

一.const

        const很初学者看到这个东西都会很头疼,不知道究竟是什么东西,那么久简单地一句话总结一下,这句话 不一定对,只是方便记忆和理解。

1.const是什么究竟怎么看

        const:const先作用于左边,若左边没有东西,就便会作用于右边。(重点)

        我们来看几个例子

const int

int const  //这以上两个就不多做解释,他们是一样的

const int* //const作用于右边,所以是指针指向的内容不可改变

int* const //const作用于左边,所以是指针不可改变,也可叫常量指针

const int* const //将上面两个综合一下 

        好的,新手肯定说哦我的头已经开始晕了,咱们就拿那句话就能得出结论(看注释)。就拿那简单的一句话来看,百分之99的const语句都不会出错,就不用看某某某老师,某某某教育机构的长篇大论,越听越迷糊。

2.顶层const与底层const

(1)如何看是顶层还是底层const

        还是用我自己的话来说,它方便大家记忆和理解

        只要const是修饰的对象或者类型本身,那么这个const就是顶层const。(重点)

        我们还是举例来说明一下

const int* const 
//左边的const修饰的是这个指针指向的类型并不是这个指针对象座椅它不是顶层const而是底层const
//右边的const修饰的是这个指针对象本身所以它是顶层const
//总体而言他是个既是底层有是顶层的const

const int
//这种const永远是顶层const

const int&
//因为& 其实就是指针的一种语法糖,所以这种const永远都是底层const,引用永远是没有顶层const

 (2)有何作用

        底层const会影响传入函数的对象,顶层const却不会影响,在函数传参时顶层const会被忽视掉的。 (重点)

        我们还是举例来说明一下,毕竟看这干条条的话换谁都头疼 

void Fun(const int a)
{

}
void Fun(int a)
{

}

//当我们生成时会发生以下报错
// error C2084: 函数“void Fun(const int)”已有主体

        会发生这种错误,为什么呢?我们知道了 const int 是一个顶层const,所以这两个函数他们的传参类型其实是相同的,因为const在传参时会被忽略掉,这两个函数类型都是 void(int)这种函数类型所以,报错了。咱们再看一下这个例子。

void Fun(const int* a)
{

}
void Fun(int* a)
{

}

        这回就可以完美生成没有报错,因为我们知道这个const是个底层const可以进行函数重载,如果我们把第一个修改成 void Fun(int* const a)那么他又会报错无法进行函数重载,因为他变成了修饰这个指针对象本身的顶层const,大家有兴趣可以试一试。

二:const的几个用处

const的用法和用处很多,尤其是函数重载,成员函数这里有很多疑惑的地方,我们来一一举例出const的用法。ps(上一部分已经举例了一个东东,但是我已经懒得排版了,大家不要忘了上面的东东)。

1.全局变量相关

        大家都知道全局变量他是有静态存储区的,他在程序开始时分配空间,在程序结束时析构掉。不多说了,上例子吧。(这期博客确实有点无聊,都没有有趣的例子是吧)

#include<iostream>
extern int a = 1;//与int a=1;没有区别
int main()
{
	std::cout << a << std::endl;
}

extren是干什么的,那我们这么写。

#include<iostream>
extern int a;
int main()
{
	std::cout << a << std::endl;
}

这个a是没有定义的,他只是个声明,extern他是一个链接的一个关键字,相当于一个外部链接的作用,就是我们在同项目中另一个文件定义一个全局变量,这里将会打印出那处的值。我们来看。

 

        我们可以清楚的看到打印出了100,这个就是extern的作用 。

        但const的全局变量,它默认是内部链接,如果不知道什么是链接我可能也会出一篇博客来讲,总之期待吧,可能。那我们改一下会怎么样呢?

         我们会获得到一个这样的报错: error LNK2001: 无法解析的外部符号 "int const a" (?a@@3HB)因为我们没办法获得到外部链接,不过再在左边的文件的const前加一个extern他就又可以正常输出了,这是const一个比较隐藏的小知识点。

 2.const reference 延续临时变量生命周期

        

         我们还是直接看例子吧

#include<iostream>
#include<string>
void* operator new(size_t size)
{
	std::cout << "new" << std::endl;
	return malloc(size);
}
void operator delete(void* m, size_t size)
{
	std::cout << "delete" << std::endl;
	free(m);
}
const std::string& Print(const std::string& s)
{
	std::cout << s << std::endl;
	std::cout << "I also alive" << std::endl;
	return s;
}
int main()
{
	Print("KNGG");
	return 0;
}

它的输出结果是:

         我们可以看到,临时变量的生命周期被延长了,到Print函数结束后才被“杀”掉,它有效的延长了临时变量的生命周期,要不然他该在传入后就被“杀”掉了。

3.类成员函数const重载的本质

        别说了,上代码!

#include<iostream>
#include<string>
class vector
{
private:
	int x, y;
public:
	void Print();
	void Print()const;
};
int main()
{
	vector vec;
	vec.Print();
	return 0;
}

        我们都知道在成员函数的结尾加上const可以进行重载,但实质上是怎么一回事呢,它为什么能重载?

        实质上这种成员函数在编译后会先变为非成员函数,并且会有个name mangling的过程就是改名,在编译器解析之后咱们的成员函数就会边长以下模样:

        

void Print(vector* const this);//1

void Print(const vector* const this);//2

参考前面顶层底层const所以它可以重载。

我们写一个代码来当做课后作业吧(装起来了)也是成员函数的const重载

#include<iostream>
#include<vector>
class vector
{
public:
	std::vector<int> ve;
public:
	void Print(std::size_t size)const
	{
	std::cout << (*this)[size] << std::endl;
	}
	const int& operator [](std::size_t size)const
	{
		return ve[size];
	}
	int& operator[](std::size_t size)
	{
		return const_cast<int&>(const_cast<const vector&>(*this)[size]);
	}
};
int main()
{
	vector vec;
	vec.ve = { 1,2,3,4,5,6 };
	vec.Print(3);
	return 0;
}

看能不能理解这一段代码,我过两天会把解析发在评论区中。

总结

ok以上就是const大概的内容了,当然还有很多东西没提到,也许也有错的地方还是那句话,欢迎大家来指正,谢谢大家看到这里。

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KNGG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值