当前位置: 首页 > article >正文

Effective Modern C++(1.顶层const与底层const)

1.顶层const与底层const的定义

const修饰的变量不可以改变,那么他就是顶层const,如:

const int a = 10;

那么,对于

const int *const p = new int(10);

第二个const就是顶层const,因为他修饰的是p;第一个const是底层const,因为他修饰的不是p,而是p所指向的。

引用的const一定是底层const,如:

const int &a = 10;

2.注意事项

当执行对象拷贝操作时,常量的顶层const不受什么影响,底层const必须一致

例子:

#include <iostream>
#include <string>


int main() {
	// part 1
	// 定义一个const变量,表示a不能被改变了
	const int a = 10;
	//令b = a,只拷贝了指,const属性并没有被拷贝
	int b = a;

    // part 2
	const int *const p = new int(10);
	int *p1 = p;
	int *const p2 = p;
	const int *p3 = p;

	// part 3
	int *p4 = &a;

	// part 4
	const int &r1 = 20;
	int &r2 = a;
	int &r3 = r1;


	return 0;
}

part 1

对于此代码第一部分,const int a = 10这句话其实和int a = 10是一样的,因为顶层const没有影响,可以忽略,因此可以直接执行拷贝操作,即int b = a;不会报错。

part 2

对于第二部分,首先定义了一个const int *const p = new int(10),由于顶层const可忽略,所以变成const int *p = new int(10);所以在第二行就会报错,报错信息为

就是因为int *p的类型不等于const int *p,同理,第三行也会报相同的错误,第四行才是正确的。 

part 3

对于第三部分int *p3 = &a;乍一看,a的定义变成了int a = 10,那么这句话似乎是对的,但是当对a取地址时,&a变成了指向a的地址,那么他就变成了底层const,因此,代码应该修改为:const int *p3 = &a.

part 4 

关于引用的const:

  • 引用不是对象,不进行拷贝,不满足上面的原则(蓝字部分)
  • 常量引用如果在左侧,右侧可以接任何东西

eg:

int &r1 = 40;会报错,因为a是一个引用,而引用是一个对象的别名,而40只是一个临时的数据,他不是一个对象,所以这句话是错误的;那么,如果代码改为const int &r1 = 40,这句话就不会报错

  • 非常量引用 = 常量, 报错

eg:

首先对于代码int &r4 = a,这里的a是一个const常量,值为10,说明a不可以被改变, 而r4这个引用是a的别名,他的类型不是const,说明可以使用别名对a的值进行改变,所以会报错。


http://www.kler.cn/a/145380.html

相关文章:

  • Node.js 的底层原理
  • 【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(一)
  • Baklib引领企业内容中台建设的新思路与应用案例
  • WSL 安装cuDNN
  • Databend x 沉浸式翻译 | 基于 Databend Cloud 构建高效低成本的业务数据分析体系
  • 【Linux】Linux C比较两个 IPv6 网关地址是否相等,包括前缀
  • java线程中,join()方法?
  • Vue 或者 React 中,什么情况下会用 Es6 的 Class类
  • 02 RANSAC算法 及 Python 实现
  • 电商项目高级篇-03 商品上架
  • Elasticsearch集群部署,配置head监控插件
  • 【spring(五)】SpringMvc总结 SSM整合流程
  • GitHub上8个强烈推荐的 Python 项目
  • Vue-报错No “exports“ main defined in xx
  • Leetcode.1590 使数组和能被 P 整除
  • Spring面向切面编程(AOP);Spring控制反转(IOC);解释一下Spring AOP里面的几个名词;Spring 的 IoC支持哪些功能
  • Java中wait()方法在synchronized方法中调用的奥秘
  • php订单发起退款(余额和微信支付)
  • STL: 容器适配器stack 与 queue
  • 什么是proxy代理?
  • NX二次开发UF_CURVE_ask_joined_parms 函数介绍
  • 存算一体还是存算分离?谈谈数据库基础设施的架构选择
  • DDD(领域驱动设计)一些基础概念
  • 【MySQL】JDBC编程
  • 【JVM系列】- 穿插·对象的实例化与直接内存
  • spring boot整合Jasypt实现配置加密