C++之旅——const简介

本人是一名在校大学生,此博客只为个人学习而用,不做商用!(反正也没人用)

如有错误,还请包含,顺便私聊一下我,要不然错漏百出的博客要被人笑话了2333333


在最近的c++之旅中,我多次看到const,一开始并没有太多关注,但是到了后来const的用法越来越复杂,我意识到了一点———我tmd已经忘了const怎么用了,忘了const的用法。所以,这次研究一下const。

  1.  const与指针

当处理const指针时,编译器将努力避免存储分配并进行型常量折叠。

常量折叠:在编译时间简单化常量表达的一个过程。简单来说就是将常量表达式计算求值,并用求得的值来替换表达式,放入常量表。可以算作一种编译优化。

在数组中,我们经常见到这样的写法。

const  int ten=10;
int a[ten];

这种写法,便是常量折叠。

 

 

 我们在使用const来修饰指针时,面临着两种选择。

int *const p;//修饰指针 ,所以这个指针是const类型的。


int const *q;//修饰指针所指的内容
const int *q;
//q是一个指向恰好是const的int的普通指针

 

 

 接下来我们写一段简单的代码来看看二者的不同。

#include<iostream>
using namespace std;
int main(void)
{
	int a[] = {0,1,2,3,4,5,6,7,8,9};
	int b[] = {1,2,3,4,5,6,7,8,9};
	int *const p=a;
	int const*q;
	cout << "p=" << *p << endl;
	q = b;
	cout << "q=" << *q << endl;
	q = a;
	cout << "new q=" << *q << endl;
	*p = 5;
	cout << *p << endl;
	p = b;//Error
	*q = 5;//Error
	return 0;
}

 

在出现Error之前的结果: 

 

定义的p指针,是一个const指针,所以在经过初始化之后,p不能被改变;

定义的q指针, 是一个指向const数据类型的指针,其指向内容是无法更改的。


2.类与const与引用

之所以在这里加上“引用”,是因为我就是被引用和const搞烦的。并且引用在函数参数以及返回值上和const有很多的操作配合,因此我在这里带上引用,一起来讨论讨论。 

  • 首先讲小结:

    const成员函数可以访问非const对象的非const数据成员、const数据成员,也可以访问const对象内的所有数据成员;

    非const成员函数可以访问非const对象的非const数据成员、const数据成员,但不可以访问const对象的任意数据成员;

    出处在这里,懒得写直接找的。

  • 类里的const

常数表达式使用常量的地方之一是在类里。但这不是我们想讨论的重点,我觉得重点应该放在成员函数的const及引用上。

首先我们先复习一下引用及其物理意义。

引用在定义时与定义指针相似,只是用&代替了*。其物理意义在地址层面上一样的,都是与原对象/变量相同的地址。但引用实质上是一种“马甲”,也就是说,在传递参数的时候,引用并没有像按值传递那样刻录副本,也没有像指针那样新建了个指针变量去指向原变量。

使用引用的意义,更多是为了节省时间。在进行传参或者返回值得时候,不使用引用的函数,会进行两次复制,首先是被复制到一个临时位置,再使用这个临时位置赋值给参数或者返回值。但是使用引用,只需要进行一次复制就可以完成这项工作。

引用是一种换了个“马甲”的本身,在物理层面上也只是苦主本体罢了。(为什么我脑子里突然出现了苦主两个字?)

 

  • const对象和成员函数

const修饰成员函数的返回值

#pragma once
class test
{
private:
	int a;
	const int b;
public:
	test();
	~test();
	const int show(int x);//const修饰成员函数的返回值
};

 

在这里,const实际上是没有用处的,因为它修饰的是返回值为const,但是按值传递的返回值并无太大意义。所以这时,const可加可不加。

 

const成员函数

const成员函数的定义其实非常简单,但它不是仅仅直接把const放在函数前就可以。当然你放在函数前只是表明它的返回值为const,并不是这个成员函数本身是const的。

定义const成员函数:

#pragma once
#include<iostream>
using namespace std;
	class test
	{
	private:
		int a=1;
		const int b=19;
	public:
		test();
		~test();
		const int show(const int q,int x);//const修饰成员函数的返回值
		int show(const int z,int s) const;
	};



我们没发现非const成员函数和const成员函数有什么不同点,相反现在看到的都是他们所拥有的共同功能——调用const数据和非const数据。

但是从他的调用来看,我们则可以看到一些端倪。

//test.cpp
#include "test.h"


test::test()
{
	a = 2;
}


test::~test()
{
}

const int test::show(const int q,int x)
{
	cout <<"a="<< x << endl;
	cout <<"b="<< q << endl;
	return 0;
}

int test::show(const int z, int s) const
{
	cout << "b=" << z << endl;
	cout << "a=" << s << endl;
	return 0;
}

 

#include"test.h"
int main(void)
{
	const test test1;//const对象
	test test2;//非const对象
	test1.show(1, 1);
	test2.show(1, 1);
	system("pause");
	return 0;
}

运行结果:

我们注意到,非const对象调用了非const成员函数,const对象调用了const成员函数

那么const对象能调用非const成员函数,非const对象能调用const成员函数吗?

前者可以,后者不行。

代码不贴了,懒。

 

当const遇到引用,又会碰撞出什么火花呢??

首先我们先看看有哪些用法

  1. int const& 和 const int&
  2. const int& f() const

首先来看第一个,这个其实是一个意思,我估计大家也都明白这点,所以我们直接跳过,来看看第二个是什么意思。

如果真的不知道,那么就阅读这里吧:

int const &和const int&是一个意思,都是表示是一个const的int类型。

const int &f()const,我们先从后面入手,那么很简单:第二个const是为了使函数能够被const和非const对象调用,且不会在函数调用中发生改变数据的行为。引用就很简单,告诉我们以及计算机,将要返回一个int类型的引用。最后就是这个返回的引用是不允许被修改的,是属于const类型的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值