重庆建设网站的公司哪家好,手工外包加工网可信吗,凉州区住房城乡建设局网站,湖北省住房和城乡建设厅官网类和对象下#xff08;this指针补充#xff09; 类和对象中构造函数和析构函数 一.this补充#xff1a;1.概念总结#xff1a;2.两个问题#xff1a; 二.构造函数和析构函数#xff1a;一.类的默认构造#xff1a;1.初始化和清理#xff1a;2.拷贝复制#xff1a;3.取… 类和对象下this指针补充 类和对象中构造函数和析构函数 一.this补充1.概念总结2.两个问题 二.构造函数和析构函数一.类的默认构造1.初始化和清理2.拷贝复制3.取地址重载 二.构造函数1.概念2.特征总结1.默认构造2.默认构造的作用2-1表面2-2内涵 二.析构函数1.概念2.特征总结3.意义 一.this补充
1.概念总结 1.this 的作为成员函数的形参的时候满足 类的类型 * const this满足这样一个情况说明this指针是不可以被修改的。 2.只能在成员函数的内部去使用 3.this指针本质上是成员函数的一个隐藏的形参通过外面的实参传给形参。实参其实是对象的地址。对象本身不回去存贮this。 4.this指针是成员函数的第一个隐藏的指针形参通过ecx寄存器把地址值传过去的不需要程序员进行处理。 5.this指针在成员函数中是可以去使用的。 2.两个问题 1.this指针存在哪里 1-1:存在函数栈帧里面。 1-2vs 2022 通过ecx寄存器进行存贮 2.this指针可以为空吗 this指针可以为空但是这个this指针作为成员函数的时候不可以去访问类的成员变量只能访问成员函数中不需要访问成员变量的一些函数是不会出问题的。 二.构造函数和析构函数
一.类的默认构造 1.当一个类是空类的时候会默认生成6个默认构造。 1.初始化和清理 1-1:构造函数主要完成成员变量的初始化工作 1-2析构函数主要完成清理工作 2.拷贝复制 2-1:拷贝构造是使用同类对象初始化创建对象 2-2赋值重载主要是是把一个对象赋值给另一个对象。 3.取地址重载 3-1:主要是普通对象和const对象取地址这两个很少会自己实现 二.构造函数
1.概念 构造函数是一个比较特殊的函数他会在对象初始化的时候由编译器进行自动调用而且只会在一个对象的生命周期中只会去调用一次。 2.特征总结 1.构造函数名称和类名称相同 2.构造函数没有返回值 3.构造函数在对象初始化的时候由编译器自己调用 //我们的构造函数在这里进行了显示类型的构造 4.构造函数是可以重载的 4-1函数的无参的构造函数和全缺省的初始化都是正常定义一个对象 4-2对象的初始化显示的去传参数。 5.5. 如果类中没有进行显示的定义构造函数那么C编译器会默认生成一个无参的默认构造。 1.默认构造
1.用户没有显示的构造函数其他操作的什么都没有生成随机值。 2.构造函数没有参数也是一种默认构造。 3.构造函数全部缺省也是一种默认构造 4.总结我们在进行对象初始化的时候不需要进行参数的传递编译器就回去调用默认构造。
2.默认构造的作用 2-1表面
我们下面实现了一个栈这个类如果我们使用默认构造调用的了默认构造函数进行初始化 #includeiostream
#includestdlib.h
#includeassert.husing namespace std;class Stack
{
public://1.初始化Stack(int capacity_num 5){int* tmp (int*)malloc(sizeof(int) * capacity_num);if (tmp nullptr){perror(malloc file);exit(-1);}arr tmp;sz 0;capacity 5;}//2.判断栈空bool Empty(){assert(arr ! nullptr);if (sz 0){return true;}return false;}//3.压栈void Push(int x){assert(arr ! nullptr);if (sz capacity){int* tmp (int*)realloc(arr, sizeof(int) * (capacity * 2));if (tmp nullptr){perror(realloc file);exit(-1);}arr tmp;capacity * 2;}arr[sz] x;}//4.获取栈顶元素int top(){assert(arr ! nullptr);if (!Empty()){return arr[sz];}}//5.删除栈顶元素void del(){assert(arr ! nullptr);if (!Empty()){arr[sz--] 0;}}//6.打印栈中数据void print(){assert(arr ! nullptr);if (!Empty()){for (int i 0; i sz; i){cout arr[i] -;}cout endl;}}
private:int* arr;int sz;int capacity;
};int main()
{Stack s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);s1.print();s1.del();s1.del();s1.print();return 0;
}2-2内涵
C把类型分成内置类型(基本类型)和自定义类型。内置类型就是语言提供的数据类型如int/char…自定义类型就是我们使用class/struct/union等自己定义的类型看看下面的程序就会发现编译器生成默认的构造函数会对自定类型成员_t调用的它的默认成员函数。 我们下面实现一个自己通过栈实现的队列 2-2重要根据上面的图片我们知道内置类型是不会去处理的自定义类型会去调用他自己默认构造
2-2根据这个问题我们C 11 支持了变量在声明的时候给一个初始值一般是面对的是内置类型因为内置类型不会去处理 //2.栈实现队列class Myqueue
{
public://1.入队列void my_push(int x){push.Push(x);sum;}//2.出队列void my_pop(){if (!pop.Empty()){while (!push.Empty()){pop.Push(push.top());push.del();}}pop.del();sum--;}//3.获取队头元素int get_top(){if (pop.Empty()){while (!push.Empty()){int tmp push.top();pop.Push(tmp);push.del();}}return pop.top();}//4.判断队列是否为空bool Eppty(){if (sum 0){return false;}return true;}
private:Stack push;Stack pop;//注意C11 中针对内置类型成员不初始化的缺陷又打了一个补丁//内置类型成员变量在类中声明的时候可以给默认值int sum 0;
};int main()
{Myqueue Q1;return 0;
}二.析构函数
1.概念
析构函数与构造函数功能相反析构函数不是完成对对象本身的销毁局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数完成对象中资源的清理工作。
2.特征总结 1.函数名和类名相同但是需要在前面加上一个~按位取反 2.没有参数没有返回类型 3. 对象生命周期结束时C编译系统系统自动调用析构函数 4. 一个类只能有一个析构函数。若未显式定义系统会自动生成默认的析构函数。注意析构函数不能重载。 3.意义 栈这样的类的析构才是有意义的 #includeiostream
#includestdlib.h
#includeassert.husing namespace std;class Stack
{
public://1.初始化Stack(int capacity_num 5){int* tmp (int*)malloc(sizeof(int) * capacity_num);if (tmp nullptr){perror(malloc file);exit(-1);}arr tmp;sz 0;capacity 5;}//2.判断栈空bool Empty(){assert(arr ! nullptr);if (sz 0){return true;}return false;}//3.压栈void Push(int x){assert(arr ! nullptr);if (sz capacity){int* tmp (int*)realloc(arr, sizeof(int) * (capacity * 2));if (tmp nullptr){perror(realloc file);exit(-1);}arr tmp;capacity * 2;}arr[sz] x;}//4.获取栈顶元素int top(){assert(arr ! nullptr);if (!Empty()){return arr[sz];}}//5.删除栈顶元素void del(){assert(arr ! nullptr);if (!Empty()){arr[sz--] 0;}}//6.打印栈中数据void print(){assert(arr ! nullptr);if (!Empty()){for (int i 0; i sz; i){cout arr[i] -;}cout endl;}}//7.栈中数据的清理~Stack(){free(arr);arr nullptr;sz 0;capacity 0;}
private:int* arr;int sz;int capacity;
};//2.栈实现队列class Myqueue
{
public://1.入队列void my_push(int x){push.Push(x);sum;}//2.出队列void my_pop(){if (!pop.Empty()){while (!push.Empty()){pop.Push(push.top());push.del();}}pop.del();sum--;}//3.获取队头元素int get_top(){if (pop.Empty()){while (!push.Empty()){int tmp push.top();pop.Push(tmp);push.del();}}return pop.top();}//4.判断队列是否为空bool Eppty(){if (sum 0){return false;}return true;}
private:Stack push;Stack pop;//注意C11 中针对内置类型成员不初始化的缺陷又打了一个补丁//内置类型成员变量在类中声明的时候可以给默认值int sum 5;
};int main()
{Stack s1;return 0;
}1.通过观察下面的动图我们可以发现在主函数栈帧结束以后我们的类对象开辟的空间被释放了 2.我们观察一下我们实现队列的默认构造和默认析构