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

小学生学C++编程语法知识(如果想将某个类用作基类,为什么该类必须定义而并非声明)


如果想将某个类用作基类,为什么该类必须定义而并非声明

对小学生来说,可以把它理解成:

继承就像“盖房子”,建新房子之前,必须知道老房子的完整结构,而不能只知道一个名字。

下面我们一步一步讲。


一、先认识两个概念:声明 vs 定义

在 C++ 中:

1. 声明(Declaration)

声明只是告诉编译器:

“有这么一个东西存在。”


例如:

class Animal;

这句话叫:

类的前向声明(forward declaration)


意思:

“以后会有一个叫 Animal 的类。”

但是编译器不知道:

  • Animal 有几个成员变量?

  • Animal 有哪些函数?

  • Animal 占多少内存?

它只知道:

有这么一个名字。


2. 定义(Definition)

定义就是完整写出类:

class Animal { public: int age; void eat() { cout << "吃东西"; } };

现在编译器知道:

Animal:

  • 有一个 int 类型的 age

  • 有一个 eat 函数

  • 大小是多少

  • 如何创建对象


二、什么叫“作为基类”?

例如:

class Dog : public Animal { };

意思:

Dog 继承 Animal。


可以理解:

Animal | | Dog

Dog 是 Animal 的孩子。


三、为什么基类必须定义?

因为创建 Dog 的时候:

Dog 身体里面包含 Animal 的部分。

例如:

class Animal { public: int age; }; class Dog : public Animal { };

实际上:

Dog对象 +----------------+ | Animal部分 | | | | age | +----------------+ | Dog自己的部分 | +----------------+

Dog 天生带有 Animal。

所以编译器必须知道:

Animal 到底有多大?


四、如果只有声明,会发生什么?

例如:

class Animal; // 只有声明 class Dog : public Animal { };

编译器看到:

Dog继承Animal

它会问:

“Animal是什么样?”

可是它只知道:

Animal这个名字存在

不知道:

Animal里面有什么

所以无法计算:

Dog对象占多少空间

例如:

Dog dog;

编译器需要分配:

多少字节?

但是:

Animal??? 大小未知

所以错误。


五、用盖房子的故事理解

假设:

爸爸 Animal 要给孩子 Dog 留房间。

爸爸房间:

+----------------+ | 爸爸的房间 | | 10平方米 | +----------------+

孩子:

Dog = 爸爸房间 + 自己房间

那么建 Dog 房子之前:

必须知道爸爸房间多大。

如果只听说:

“有一个爸爸。”

但是不知道:

  • 爸爸房间多大

  • 有几个房间

怎么建?

所以:

继承必须知道基类完整结构。


六、为什么普通指针可以只声明?

这里容易混淆。

例如:

class Animal; Animal* p;

可以。

为什么?

因为:

指针大小固定。

比如:

64位系统:

指针 = 8字节

编译器只需要知道:

“这是一个地址。”

不需要知道 Animal 有多大。


但是:

class Dog : public Animal { };

不行。

因为:

Dog包含Animal。

必须知道:

Animal大小

七、一个经典对比

情况1:指向对象

可以:

class Student; Student* p;

因为:

只需要保存地址。


情况2:继承

不可以:

class Student; class GoodStudent : public Student { };

因为:

GoodStudent需要包含Student。


八、还有一个重要原因:虚函数表

如果基类有虚函数:

class Animal { public: virtual void speak(); };

那么对象里面还有:

虚函数表指针 vptr

例如:

Animal对象 +-------------+ | vptr | +-------------+ | 成员变量 | +-------------+

派生类:

Dog对象 +-------------+ | Animal部分 | | vptr | +-------------+ | Dog部分 | +-------------+

如果不知道 Animal 定义:

连:

  • 有没有虚函数

  • 有没有vptr

  • 内存布局

都不知道。

所以更加不能继承。


九、总结成一句小学生能记住的话

为什么基类必须定义?

因为:

派生类像是在基类身体上继续添加东西,编译器必须先知道基类完整长什么样,才能计算派生类的大小和布局。


口诀:

声明: 知道名字,不知道身体 定义: 知道身体,知道大小 指针: 只需要知道名字 继承: 必须知道身体

十、和前面“虚析构函数”的知识联系起来

以后学习:

class Base { public: virtual ~Base() { } }; class Derived : public Base { };

这里:

Derived继承Base。

编译器必须知道:

Base完整定义。

因为:

Derived对象里面包含Base部分。

所以:

继承关系比指针关系要求更多的信息。


这也是为什么:

class Base; Base* p; // 可以 class Derived : public Base { }; // 不可以

这是 C++ 面向对象中非常核心的规则。


http://www.jsqmd.com/news/1359307/

相关文章:

  • 腾讯云Docker部署OpenClaw全攻略:从零搭建AI智能体生产环境
  • UReport2架构解析:基于单元格迭代模型的高性能Java报表引擎实战方案
  • OpenClaw AI智能体框架VPS部署实战:从选型到上线的完整指南
  • ZonyLrcToolsX:跨平台歌词下载工具的终极解决方案
  • 计算机组成原理第四章 指令系统
  • SpaceX零现金“接管”Cursor:AI编程工具如何重塑硬核工程开发范式
  • 三步激活指南:KMS智能工具实现Windows与Office永久激活的完整流程
  • 上位机开发必备:UTF-8编码原理与实战指南
  • 智能电网中分布式能源系统的多目标优化控制策略
  • 太原瓷砖胶口碑排名
  • 2026年8月上海青浦区离婚律所哪家强?5家长三角一体化区域家事律所推荐 - 品牌深度评测
  • 5分钟打造专业影院体验:MPV懒人包终极配置指南
  • 双路磁场定向控制电机驱动板终极指南:240W高性能开源解决方案
  • 送给爱健身的男朋友什么七夕礼物好?这份硬核健康礼清单请收好 - 品牌品鉴馆
  • 如何永久保存微信聊天记录?3大核心功能实现个人数据备份与智能分析
  • AMD AI开发实战指南:从ROCm环境搭建到PyTorch部署
  • Spring Boot Starter机制解析与自定义开发实战
  • 本地做led显示屏工程的靠谱公司避坑测评,价格透明口碑实力之选 - myqiye
  • 原来重庆正规校园广播销售门道不少,哪家才好呢?
  • Qwen-Image-3.0 高分辨率图像生成API实战:低成本接入与工程化指南
  • 8-PSK调制系统实现与误码性能分析
  • 告别DLL错误:Visual C++运行库全集一键安装指南
  • 5分钟快速解决Windows老游戏兼容性问题:DDrawCompat完整使用指南
  • 小学生学C++编程语法知识(什么情况下会自动生成默认构造函数)
  • 2026年广佛办公家具回收服务商**:实体仓储、透明报价与全流程托管 - 品牌品鉴馆
  • 2026年8月上海奉贤区离婚律所哪家专业?6家新城家事法律服务团队解析 - 品牌深度评测
  • PlayCover终极指南:如何在M1/M2 Mac上免费运行iOS应用和游戏
  • 2026铝塑共挤窗服务厂商口碑推荐强势出炉,实力测评不踩坑 - myqiye
  • SunnyUI:用100+控件库彻底改变你的C WinForm开发体验
  • 基于用户行为数据的风格偏好建模与个性化推荐系统实战