小工具知识网

当前位置: 首页 > 行业知识 > 【C++那些事儿】深入理解C++类与对象:从概念到实践(上)| 揭开this指针的神秘面纱

行业知识

【C++那些事儿】深入理解C++类与对象:从概念到实践(上)| 揭开this指针的神秘面纱

2026-10-30 22:13:48 来源:互联网转载
���池俊: 个人主页

个人专栏: ✅数据结构冒险记 ✅C++那些事儿

有航道的人,再渺小也不会迷途。


文章目录

    • 1. 面向过程和面向对象初步认识
    • 2.类的引入
    • 3.类的定义
    • 4.类的访问限定符及封装
      • 4.1 访问限定符
      • 【面试题】
        • 问题:C++中struct和class的区别是什么?
        • 4.2 封装
        • 【面试题】
          • 在类和对象阶段,主要是研究类的封装特性,那什么是封装呢?
          • 5.类的作用域
          • 6.类的实例化
          • 7.类对象模型
            • 7.1 如何计算类对象的大小
            • `问题:类中既可以有成员变量,又可以有成员函数,那么一个类的对象中包含了什么?如何计算一个类的大小?`
            • 7.2 类对象的存储方式猜测
              • 1. 对象中包含类的各个成员
              • 2. 代码只保存一份,在对象中保存存放代码的地址
              • 3. 只保存成员变量,成员函数存放在公共的代码段
              • 7.3 结构体内存对齐规则
              • 8.this指针
                • 8.1 this指针的引出
                • 8.2 this指针的特性
                • 【面试题】
                  • 1. this指针存在哪里?
                  • 2. this指针可以为空吗?
                  • 8.3. C语言和C++实现Stack的对比
                    • 1. C语言实现
                    • 2. C++实现

                      1. 面向过程和面向对象初步认识

                      C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。

                      C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。

                      2.类的引入

                      C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如:之前在数据结构初阶中,用C语言方式实现的栈,结构体中只能定义变量;现在以C++方式实现,会发现struct中也可以定义函数。

                      #include#includeusing namespace std;typedef int DataType;struct Stack{// 初始化void Init(size_t capacity){_array = (DataType*)malloc(sizeof(DataType) * capacity);if (nullptr == _array){perror("malloc申请空间失败");return;}_capacity = capacity;_size = 0;}// 入栈void Push(const DataType& data){// 扩容_array[_size] = data;++_size;}// 取栈顶元素DataType Top(){return _array[_size - 1];}// 销毁栈void Destroy(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}DataType* _array;size_t _capacity;size_t _size;};int main(){Stack s;s.Init(10);s.Push(1);s.Push(2);s.Push(3);cout // 类体:由成员函数和成员变量组成};  // 一定要注意后面的分号public:void Init(int year){// 这里的year到底是成员变量,还是函数形参?year = year;}private:int year;};// 所以一般都建议这样class Date{public:void Init(int year){_year = year;}private:int _year;};// 或者这样class Date{public:void Init(int year){mYear = year;}private:int mYear;};// 其他方式也可以的。一般都是加个前缀或者后缀标识区分就行。public:// 成员函数声明void PrintPersonInfo();private:char _name[20];char _gender[3];int  _age;};// 这里需要指定PrintPersonInfo是属于Person这个类域(成员函数类外定义)void Person::PrintPersonInfo(){cout Person._age = 100;   // 编译失败:error C2059: 语法错误:“.”return 0;}public:void PrintA(){cout public:void f1() {}private:int _a;};// 类中仅有成员函数class A2 {public:void f2() {}};// 类中什么都没有---空类class A3{};int main(){cout public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout Date d1, d2;d1.Init(2022, 1, 11);d2.Init(2022, 1, 12);d1.Print();d2.Print();return 0;}public:void PrintA(){cout A* p = nullptr;p-PrintA();return 0;}// 答案:C、正常运行// 原因:PrintA函数不在某个实例化的对象中,而是在公共代码区,所以p不会解引用,但是此处的p的作用是作为函数实参传递给函数第一个隐含的this指针。// 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行class A{public:void PrintA(){cout A* p = nullptr;p-PrintA();return 0;}// 答案:B、运行崩溃// 原因:PrintA函数中访问了成员函数_a,而_a的访问需要解引用this指针,但此时的this指针就是p,p是空指针,空指针解引用导致程序运行崩溃DataType* array;int capacity;int size;}Stack;void StackInit(Stack* ps){assert(ps);ps-array = (DataType*)malloc(sizeof(DataType) * 3);if (NULL == ps-array){assert(0);return;}ps-capacity = 3;ps-size = 0;}void StackDestroy(Stack* ps){assert(ps);if (ps-array){free(ps-array);ps-array = NULL;ps-capacity = 0;ps-size = 0;}}void CheckCapacity(Stack* ps){if (ps-size == ps-capacity){int newcapacity = ps-capacity * 2;DataType* temp = (DataType*)realloc(ps-array,newcapacity * sizeof(DataType));if (temp == NULL){perror("realloc申请空间失败!!!");return;}ps-array = temp;ps-capacity = newcapacity;}}void StackPush(Stack* ps, DataType data){assert(ps);CheckCapacity(ps);ps-array[ps-size] = data;ps-size++;}int StackEmpty(Stack* ps){assert(ps);return 0 == ps-size;}void StackPop(Stack* ps){if (StackEmpty(ps))return;ps-size--;}DataType StackTop(Stack* ps){assert(!StackEmpty(ps));return ps-array[ps-size - 1];}int StackSize(Stack* ps){assert(ps);return ps-size;}int main(){Stack s;StackInit(&s);StackPush(&s, 1);StackPush(&s, 2);StackPush(&s, 3);StackPush(&s, 4);printf("%d\n", StackTop(&s));printf("%d\n", StackSize(&s));StackPop(&s);StackPop(&s);printf("%d\n", StackTop(&s));printf("%d\n", StackSize(&s));StackDestroy(&s);return 0;}public:void Init(){_array = (DataType*)malloc(sizeof(DataType) * 3);if (NULL == _array){perror("malloc申请空间失败!!!");return;}_capacity = 3;_size = 0;}void Push(DataType data){CheckCapacity();_array[_size] = data;_size++;}void Pop(){if (Empty())return;_size--;}DataType Top() { return _array[_size - 1]; }int Empty() { return 0 == _size; }int Size() { return _size; }void Destroy(){if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}}private:void CheckCapacity(){if (_size == _capacity){int newcapacity = _capacity * 2;DataType* temp = (DataType*)realloc(_array, newcapacity *sizeof(DataType));if (temp == NULL){perror("realloc申请空间失败!!!");return;}_array = temp;_capacity = newcapacity;}}private:DataType* _array;int _capacity;int _size;};int main(){Stack s;s.Init();s.Push(1);s.Push(2);s.Push(3);s.Push(4);printf("%d\n", s.Top());printf("%d\n", s.Size());s.Pop();s.Pop();printf("%d\n", s.Top());printf("%d\n", s.Size());s.Destroy();return 0;}

上一篇:谷歌邮箱怎么上?

下一篇:BP神经网络的MATLAB实现(含源代码)