[cpp primer随笔] 16. 【不完整类型】的概念

news/2024/11/30 14:43:57/

我相信很多人都曾在学习C++的过程中,像下面这样干过:

class Example{Example obj; // error: 不允许使用不完整的类型
};

即在类A中,定义A类型的成员变量。此时编译是无法通过的,我们会得到不允许使用不完整的类型这样冷冰冰的报错。

这就引出了这篇文章要分享的话题:什么是【不完整类型】?


与函数相同,类类型的定义可以拆分为声明与定义两部分。

class Example; // 声明class Example{ // 声明 + 定义// ...
};

声明的作用是在当前的作用域环境下,使类名可见。定义的作用则是指定该类型所拥有的具体成员。只要一个类型完成了声明,那么编译器就会意识到有这样一个类型存在。但只要该类类型的定义没有完成,这就是一个不完整类型。

不完整类型是指只进行了声明,却没有完成定义的类类型。

在最开始的例子中,由于Example的定义尚未完全结束,此时Example属于不完整类型,这便是报错的原因。

那么为什么C++禁止使用不完整类型呢?

因为,将类型本身用于定义成员变量,是一件很逆天的事情。因为你无法确定在这种层层嵌套下,一个该类型对象的大小究竟是多少!这样程序将无法有效分配内存空间。为此,必须杜绝使用不完整类型来定义变量。

但若将上面的例子改一下,我们将Example类型的成员换成其指针类型Example*,编译是可以通过的。

class Example{
private:Example * p_obj; // 编译通过
};

因为指针类型是完整的,无论指向的何种类型,只需确保该种类型的名字在当前作用域下可见即可。 另外,从确定成员所占大小的角度考虑,在C++中,指针的大小是固定的,与指向的具体类型无关。


http://www.ppmy.cn/news/1198278.html

相关文章

C++ 复制控制之复制构造函数

C类用三个特殊的成员函数:复制构造函数、赋值操作符和析构函数 来决定类对象之间的初始化或赋值时发生什么。所谓的“复制控制”即通过这三个成员函数控制对象复制的过程 复制构造函数首先是一个构造函数,它同所有其他的构造函数一样与类同名&#xff0…

【微服务】mysql + elasticsearch数据双写设计与实现

目录 一、前言 二、为什么使用mysqles双写 2.1 单用mysql的问题 2.2 为什么不直接使用es 2.2.1 非关系型表达 2.2.2 不支持事务 2.2.3 多字段将造成性能低下 三、mysqles双写方案设计要点 3.1 全新设计 VS 中途调整架构 3.2 全表映射 VS 关键字段存储 3.2.1 最大程度…

IO学习系列之阻塞IO

阻塞IO:若资源没有准备就绪,会阻塞等待资源;若资源准备就绪,会获取相关资源;特点:在所有的IO模型中,阻塞IO是最简单、最常用、效率最低的;写阻塞:如无名管道、有名管道等…

vector类模拟实现(c++)(学习笔记)

vector 构造函数析构函数[]push_backsize()capacity()reserve()push_back() 迭代器实现非const和const版本 pop_back()resize()insert()***重点erase()***重点再谈构造函数!拷贝构造函数****(重点)运算符重载***(重点)…

单接口多个实现类调用指定类失效问题排查

背景描述 最近在做数据库大表拆分接ES的优化需求,针对某个大表数据逻辑接口IPoolProductService,增加策略实现类PoolProductProxyService,用于控制访问走老逻辑PoolProductService还是新逻辑PoolProductInfoService。 数据逻辑接口IPoolPro…

JS匿名函数之函数表达式与立即执行函数

匿名函数是什么?和具名函数有什么区别?让我为大家介绍一下吧! 没有名字的函数,无法直接使用 一.函数表达式 将匿名函数赋值给一个变量,并且通过变量名去调用,我们将这个称为函数表达式 语法: …

R语言 复习 习题图片

这是日天土申哥不知道从哪淘来的R语言复习知识点图片,大部分内容都是课后习题的答案 加油吧,骚年,考个好分数

算法升级之路(六) 合并两个有序数组

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。 注意:最终,合并后数组…