C++难点三:const修饰指针究竟是什么不变,以及引用的本质:const指针

const的3种用法:

1. 常量指针

2. 指向常量的指针(而不是什么“指针常量”)

关于1和2 黑马程序员上讲的不对。我重新看了C++ primer,进行了更正。

3. 指针and常量

#include <iostream>
using namespace std;

int main() 
{
	int a=10;
	int b=20;
	
	//1.常量指针(从右向左读) 说明指针是常量 也即指针存的那个地址是常量 而不是地址指向的值是常量
	int *const p1=&a;
	//p1=&b;//p1不可以变
	*p1=20;//*p1可以变
	
	//2.指向常量的指针 指针指向的*p不可以变
	const int *p2=&a;
	//*p2=30;*p2不可以变
	p2=&b;//p2可以变
	
	//3.修饰 指针and常量 俩都不能变
	const int* const p3=&a;
    //*p3=30;*p3不可以变
	//p3=&b;p3不可以变
    
	return 0;
}

引用的本质:

引用在C++里的实现本质其实就是上述第二种,也即指针常量
我们可以看一下,内部是怎么实现的:
我们写的代码:

int a = 10;
int &b = a;//b是a的别名,也即对a的一个引用
b = 20;//a和b都变成20

本质上,C++编译器解释出来的代码:

int a = 10;
int* const b = &a;
*b = 20; 

带来的性质:

  1. 由于有个const,所以p指向一旦引用之后就不能变成对其它变量的引用,如:
 int a = 10, c = 20;
 int& b = a;//b是a的引用
 b = c;//这句话并不是说b变成c的引用了,而是a、b、c全变成20
  1. 引用与指针的区别:引用不可以为空(一开始初始化的时候就要赋值,而指针可以一开始为NULL)
  2. 常量引用的用途:用来修饰形参,防止误操作。
    ①比如,如果不进行常量引用,是不能int &b = 10的:
int a = 10;
// int &b = 10; 不可以!因为引用只能对四区(栈区、堆区、全局区、代码区)中的栈区、堆区进行操作,而10是个常量,在全局区中)
int &b=a;//可以,a是局部变量,会在栈区

         ②但是,如果进行常量引用,在int 前加一个const变成const int &b = 10就正确,这里正确只是因为编译器解释的时候内部自主解释成int temp = 10; const int &b = temp
此处多说一句:正因为int& b = 10不正确,const int& b =10正确,所以void func(int b){}void func(const int& b){}才可以重载。且,重载的调用:func(10)调用的是void func(const int& b),而 int b = 10;func(b);调用的是 void func(int b)
        
引申-
1.常量引用用于形参:

 void showValue(const int& a)
{
    //不可以a=1000;因为有防止误操作的const
    cout<<a<<endl;
}
int main()
{
    int a=10;
    showValue(a);
	return 0;
}

2.const修饰成员函数:成员函数后加const为常函数,不可以修改不含mutable的成员属性。

#include <iostream>
using namespace std;

class Person
{
public:
  int age;
  
  void ShowAge() const
  {
      age=3;
  }
};

int main()
{
    Person p;
    p.ShowAge();
    return 0;
}

成员函数ShowAge()后加了const,函数中不能调用成员变量age,所以代码报错。
内在原因:
每次成员函数中用到成员变量时,编译器都会自动加上一个this指针,如上方的age变为this->age。this指针的本质是指针常量Person* const this,即*p可以修改,但是p的指向不可以修改,所以p->age不可以修改。

3.常对象:常对象只能调用常函数,成员对象前加const为常对象,不可以修改不含mutable的成员属性

#include <iostream>
using namespace std;

class Person
{
public:
    Person()
    {
        
    }
    int m_A;
    mutable int m_B;
    void func1()const
    {
        
    }
    void func2()
    {
        
    }
};

int main()
{
    //常对象只能改mutable的成员变量
    const Person p;
    p.m_B=50;
    //常对象不可以改非mutable的成员变量如p.m_A=0;
    //常对象可以调用常函数如p.func1();
    p.func1();
    //常对象不可以调用非常函数如p.func2();
     return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值