news 2026/9/4 8:35:35

C++:类与对象(一)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++:类与对象(一)

本文介绍C++中类与对象的核心概念。首先讲解类的定义格式、访问限定符(public、private、protected)以及类域的作用;随后介绍对象的实例化过程、对象大小的计算规则,并解释空类为何占用一个字节;最后说明this指针的隐藏机制及其在成员函数调用中的作用。

类的定义格式

C++中的类可以简单理解为将一个功能整体打包封装,而这个打包好的东西就称之为“类”。

类中包含变量和函数,它们分别被称之为“成员变量”,“成员函数”(类的方法)。

类的定义通过class这个关键字,后面接上类的名字,比如Stack,在加上括号和分号。

#define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> #include <assert.h> using namespace std; class Stack { public: //成员函数 void Init(int n = 4) { _array = (int*)malloc(sizeof(int) * n); if (_array == NULL) { perror("malloc"); return; } _capacity = n; _top = 0; } void Push(int x) { //扩容 if (_top == _capacity) { int* tmp = (int*)realloc(_array, sizeof(int) * _capacity * 2); if (tmp == NULL) { perror("realloc"); return; } _capacity *= 2; _array = tmp; } _array[_top++] = x; } int Top() { assert(_top > 0); return _array[_top - 1]; } void Destroy() { free(_array); _array = nullptr; _top = _capacity = 0; } private: //成员变量 int* _array; size_t _capacity; size_t _top; };

访问限定符

我们还可以注意到public和private这两个关键字。

它们被称为“访问限定符”。

public修饰的成员能在类外访问,而private和protected则不能在类外访问。后两者的区别会放在后续谈。

需要注意的是,如果class定义的成员没有被访问限定符修饰,那么就会默认为private,而struct则是public。

一个习惯是,成员变量通常为private,而成员函数为public。

类域

类指定了一个新的作用域。如果你把函数声明放在类中,定义放在类外,那么定义使用域操作符"::"指定该定义到底属于那个类。

#define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> #include <assert.h> using namespace std; class Stack { public: //成员函数 void Init(int n = 4) { _array = (int*)malloc(sizeof(int) * n); if (_array == NULL) { perror("malloc"); return; } _capacity = n; _top = 0; } void Push(int x); int Top() { assert(_top > 0); return _array[_top - 1]; } void Destroy() { free(_array); _array = nullptr; _top = _capacity = 0; } private: //成员变量 int* _array; size_t _capacity; size_t _top; }; void Stack::Push(int x) { //扩容 if (_top == _capacity) { int* tmp = (int*)realloc(_array, sizeof(int) * _capacity * 2); if (tmp == NULL) { perror("realloc"); return; } _capacity *= 2; _array = tmp; } _array[_top++] = x; }

在此例中,如果不用域操作符,Push函数就会被当作全局函数处理。

对象

类的实例化

现实中,房屋都有设计图,但图中的事物是没有实体的设计,而当你按照图纸把它造出来时,它才拥有实体。

类比到这里,类就像设计图,它没有实体,也就是没有被分配内存,只有实例化——创建了对象后,那个对象才算是实体,才是被分配了内存。

int main() { Stack st1;//实例化 st1.Init(); st1.Push(1); st1.Push(2); st1.Push(3); st1.Push(4); st1.Push(5); cout << st1.Top() << endl; st1.Destroy(); return 0; }

这里顺带说一下,实例化出的对象包含每个成员变量,但不包含函数,也没有存储它们的指针。

毕竟函数总是一样的,如果每个对象都包含函数,会非常浪费空间。再一个,指针本质上是地址,编译器会在编译链接时,找到函数地址,将调用函数编译为汇编指令,而不是在运行时找。

对象的大小

对象既然有实体,那就必然有大小。它的大小计算方式和结构体类似,具体如下:

1.第一个成员对齐在偏移量为零处。

2.其它成员对齐到对齐数的整数倍的地址处。(对齐数为默认对齐数和该成员大小的较小值,VS默认对齐数是8)

3.总大小为最大对齐数的整数倍

4.如果嵌套了结构体,那么嵌套的结构体对齐到自身最大对齐数的地址处,整个结构体的大小为包含了嵌套结构体成员的最大对齐数的整数倍。

我们来看下面例子:

#include <iostream> #include <assert.h> using namespace std; class A { public: void Print() { cout << _ch << endl; } private: char _ch; int _i; }; class B { public: void Print() { } }; class C { }; int main() { A a; B b; C c; cout << sizeof(a) << endl; cout << sizeof(b) << endl; cout << sizeof(c) << endl; return 0; }

最终算出结果为:8 1 1

我们发现,在类中,即使没有成员变量,大小仍然会有一个字节。毕竟如果一个字节都不给,怎么证明这个对象存在过?这里给一个字节是为了保证不同对象有不同的地址。

this指针

在刚刚的stack类的例子中,如果我们实例化出两个对象st1,st2,那么它们所包含的函数都是相同的,可问题在于,函数体中似乎没有区分对象的功能,那在调用时,它究竟是如何决定,我是该拿st1的数据,还是st2的数据的呢?

其实每个成员函数的第一个形参隐藏了一个this指针参数,用它来访问对应对象的成员变量,字面意思上的告诉函数是”这个“对象。

比如stack的Init的真面目时是:

void Init(Stack* const this, int n = 4) { this->_array = (int*)malloc(sizeof(int) * n); if (this->_array == NULL) { perror("malloc"); return; } this->_capacity = n; this->_top = 0; }

注意,C++规定不能再实参和形参位置上显示地写this指针,但是我们可以在函数体内部显示使用this指针。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 8:19:38

Java 故障排查:GC 日志、线程堆栈、内存快照 dump 全套命令

环境准备与基础信息 环境要求&#xff1a;Linux 系统&#xff0c;JDK8 或 JDK11。 第一步&#xff1a;获取 Java 进程 PID # 方法一&#xff1a;使用 jps jps -l 方法二&#xff1a;使用 ps ps -ef | grep java 假设获取到的进程 PID 为 12345&#xff0c;下文所有命令中的…

作者头像 李华
网站建设 2026/9/4 8:52:43

场景浸入式英语学习:从机场到日常沟通的工程化实践

那天在机场候机&#xff0c;我盯着登机口屏幕上滚动的英文通知&#xff0c;突然意识到一个长久以来被自己忽略的“能力断层”。我能熟练地敲代码、看技术文档&#xff0c;甚至能快速理解一篇复杂的英文论文&#xff0c;但当广播里传来“We are now boarding passengers in Grou…

作者头像 李华
网站建设 2026/9/4 20:51:08

2026年7月日照市新房价格深度分析报告

一、报告背景与数据说明本报告基于2026年7月日照市新房实际成交案例&#xff0c;结合区域分布、楼盘定位、户型结构与成交价格等维度&#xff0c;对当前日照市新房市场进行深度分析。数据来源为2026年7月日照市各主要城区新房网签备案及典型楼盘实际成交记录&#xff0c;覆盖东…

作者头像 李华
网站建设 2026/9/4 15:23:26

游戏推理任务设计:基于状态机与对话树构建剧情解谜系统

这次我们来看一个游戏推理任务的设计与实现思路。标题提到的《食盒疑案》第六幕&#xff0c;是一个典型的剧情驱动型解谜玩法&#xff0c;核心是“传唤证人-梳理证词-找出关键道具&#xff08;食盒&#xff09;”。对于游戏开发者、剧情策划&#xff0c;或是想学习如何设计分支…

作者头像 李华
网站建设 2026/9/4 9:12:32

小数据集目标检测实战:从282张公路落石图像到工业级模型部署

简介&#xff1a;本资源是一份面向计算机视觉初学者与目标检测实践者的公路落石检测专用数据集&#xff0c;适用于YOLO系列与Pascal VOC框架下的模型训练与算法验证&#xff0c;特别适合交通场景异常物体识别的入门级项目实践。数据包共1019个文件&#xff0c;包含282张JPG实景…

作者头像 李华