博主名称键盘敲碎了雾霭 个人专栏: 《C语言》《数据结构》 《C》⛺️指尖敲代码雾霭皆可破文章目录一、类的定义1.1 类定义格式1.2 访问限定符1.3 类域二、实例化2.1 实例化概念2.2 对象大小三、this指针3.1 引入3.2 易错点四、C和C语言4.1 分析4.2 代码实现文章结语一、类的定义1.1 类定义格式class为定义类的关键字Stack为类的名字{}中为类的主体注意类定义结束时后面分号不能省略。类体中内容称为类的成员类中的变量称为类的属性或成员变量类中的函数称为类的方法或者成员函数。#includeiostreamusingnamespacestd;classStack{public:voidInit(intn4){arr(int*)malloc(sizeof(int)*n);if(arrNULL){perror(malloc);return;}capacityn;top0;}voidPush(intx){if(capacitytop){intnewcapacity2*capacity;int*ptr(int*)realloc(arr,sizeof(int)*newcapacity);if(ptrNULL){perror(realloc);return;}arrptr;capacitynewcapacity;}arr[top]x;}intTop(){returnarr[top-1];}voidDestroy(){if(arrNULL){return;}free(arr);capacitytop0;}private:int*arr;intcapacity;inttop;};intmain(){Stack st;st.Init();st.Push(1);st.Push(2);st.Push(3);coutst.Top()endl;st.Destroy();return0;}为了区分成员变量一般习惯上成员变量会加一个特殊标识如成员变量前面或者后面加或者m开头注意C中这个并不是强制的只是一些惯例具体看公司的要求。int_day;int_month;int_year;C中struct也可以定义类C兼容c中struct的用法同时struct升级成了类明显的变化是struct中可以定义函数一般情况下我们还是推荐用class定义类。C升级struct升级成了类类里面可以定义函数struct名称就可以代表类型不需要typedef定义在类面的成员函数默认为inline1.2 访问限定符C一种实现封装的方式用类将对象的属性与方法结合在一块让对象更加完善通过访问权限选择性的将其接口提供给外部的用户使用。public修饰的成员在类外可以直接被访问protected和private修饰的成员在类外不能直接被访问访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止如果后面没有访问限定符作用域就到}即类结束。class定义成员没有被访问限定符修饰时默认为privatestruct默认为public。一般成员变量都会被限制为private/protected需要给别人使用的成员函数会放为public。1.3 类域类定义了一个新的作用域类的所有成员都在类的作用域中在类体外定义成员时需要使用作用域操作符指明成员属于哪个类域。#includeiostreamusingnamespacestd;classStack{public:voidInit(intn4);private:int*arr;intcapacity;inttop;};voidStack::Init(intn){arr(int*)malloc(sizeof(int)*n);if(arrNULL){perror(malloc);return;}capacityn;top0;}二、实例化2.1 实例化概念用类类型在物理内存中创建对象的过程称为类实例化出对象。类是对象进⾏⼀种抽象描述是⼀个模型⼀样的东西限定了类有哪些成员变量这些成员变量只是声明没有分配空间⽤类实例化出对象时才会分配空间classData{//不会开空间private:int_day;int_month;int_year;};一个类可以实例化出多个对象实例化出的对象占用实际的物理空间存储类成员变量,像一张设计图纸通过它可以建多个房子Stack st1;Stack st2;2.2 对象大小类实例化出的每个对象都有独立的数据空间所以对象中肯定包含成员变量大小不包含成员函数函数指针是不需要存储的函数指针是一个地址调用函数被编译成汇编指令[call地址]其实编译器在编译链接时就要找到函数的地址不是在运行时找对象中只存储成员变量C规定类实例化的对象也要符合内存对齐的规则与C语言结构体大小类似具体看这篇文章https://blog.csdn.net/2401_89538720/article/details/154124365?fromshareblogdetailsharetypeblogdetailsharerId154124365sharereferPCsharesource2401_89538720sharefromfrom_link注意当类为空或只有函数大小不为0而为1因为如果一个字节都不给怎么表示对象存在过呢所以这里给1字节纯粹是为了占位标识对象存在。三、this指针3.1 引入classDate{public:voidInit(intday,intmonth){_dayday;_monthmonth;}voidPrint(){cout_day _monthendl;}private:int_day;int_month;};intmain(){Date d1;Date d2;d1.Init(1,2);d2.Init(3,4);d1.Print();d2.Print();}Date类中有Init与Print两个成员函数函数体中没有关于不同对象的区分那当d1调用lnit和Print函数时该函数是如何知道应该访问的是d1对象还是d2对象呢编译器编译后类的成员函数默认都会在形参第一个位置增加一个当前类类型的指针叫做this指针。类的成员函数中访问成员变量本质都是通过this指针访问的//void Init( Date* const this,int day,int month)//{// this-_day day;// this-_month month;//}C规定不能在实参和形参的位置显示的写this指针编译时编译器会处理但是可以在函数体内显示使用this指针。voidInit(intday,intmonth){this-_dayday;this-_monthmonth;}3.2 易错点classA{public:voidPrint(){couthahaendl;}};intmain(){A*pnullptr;p-Print();return0;}该程序不会报错因为nullptr存放在this指针里面没有对其解引用classA{public:voidPrint(){couthahaendl;coutaendl;}private:inta;};intmain(){A*pnullptr;p-Print();return0;}这种会报错因为this-a对空指针解引用了补充 this指针存在内存栈上VS存放在寄存器上频繁调用四、C和C语言以C和c语言实现Stack对比为例4.1 分析C中数据和函数都放到了类里面通过访问限定符进行了限制不能再随意通过对象直接修改数据C中有一些相对方便的语法比如lnit给的缺省参数会方便很多成员函数每次不需要传对象地址因为this指针隐含的传递了方便了很多使用类型不再需要typedef用类名就很方便。4.2 代码实现C语言#includestdio.h#includestdlib.htypedefintSTDatatype;typedefstructSTack{STDatatype*arr;intcapacity;inttop;}ST;voidSTInit(ST*pst){pst-arrNULL;pst-capacitypst-top0;}voidSTPush(ST*pst,STDatatype x){if(pst-capacitypst-top){STDatatype newcapacitypst-capacity0?4:pst-capacity*2;STDatatype*ptr(STDatatype*)realloc(pst-arr,sizeof(STDatatype)*newcapacity);if(ptrNULL){perror(realloc);return;}pst-arrptr;pst-capacitynewcapacity;}pst-arr[pst-top]x;}intSTTop(ST*pst){returnpst-arr[pst-top-1];}voidSTDestroy(ST*pst){if(pst-arr!NULL){free(pst-arr);}pst-capacitypst-top0;}C#includeiostreamusingnamespacestd;typedefintSTDatatype;classSTack{public:voidInit(intn4){_arr(STDatatype*)malloc(sizeof(STDatatype)*n);_capacityn;_top0;}voidPush(STDatatype x){if(_capacity_top){STDatatype newcapacity_capacity0?4:_capacity*2;STDatatype*ptr(STDatatype*)realloc(_arr,sizeof(STDatatype)*newcapacity);if(ptrNULL){perror(realloc);return;}_arrptr;_capacitynewcapacity;}_arr[_top]x;}intTop(){return_arr[_top-1];}voidDestroy(){free(_arr);_arrnullptr;_top_capacity0;}private:STDatatype*_arr;STDatatype _capacity;STDatatype _top;};文章结语感谢你读到这里我是「键盘敲碎了雾霭」愿这篇文字帮你敲开了技术里的小迷雾 如果内容对你有一点点帮助不妨给个暖心三连吧点赞| ❤️收藏| ⭐关注听说三连的小伙伴代码一次编译过bug绕着走你的支持就是我继续敲碎技术雾霭的最大动力 小彩蛋/^ ^\ / 0 0 \ V\ Y /V / - \ / | V__) ||摸一摸毛茸茸的小狗赶走所有疲惫和bug我们下篇见 ✨
【C++入门】类和对象(一):定义、实例化与this指针
博主名称键盘敲碎了雾霭 个人专栏: 《C语言》《数据结构》 《C》⛺️指尖敲代码雾霭皆可破文章目录一、类的定义1.1 类定义格式1.2 访问限定符1.3 类域二、实例化2.1 实例化概念2.2 对象大小三、this指针3.1 引入3.2 易错点四、C和C语言4.1 分析4.2 代码实现文章结语一、类的定义1.1 类定义格式class为定义类的关键字Stack为类的名字{}中为类的主体注意类定义结束时后面分号不能省略。类体中内容称为类的成员类中的变量称为类的属性或成员变量类中的函数称为类的方法或者成员函数。#includeiostreamusingnamespacestd;classStack{public:voidInit(intn4){arr(int*)malloc(sizeof(int)*n);if(arrNULL){perror(malloc);return;}capacityn;top0;}voidPush(intx){if(capacitytop){intnewcapacity2*capacity;int*ptr(int*)realloc(arr,sizeof(int)*newcapacity);if(ptrNULL){perror(realloc);return;}arrptr;capacitynewcapacity;}arr[top]x;}intTop(){returnarr[top-1];}voidDestroy(){if(arrNULL){return;}free(arr);capacitytop0;}private:int*arr;intcapacity;inttop;};intmain(){Stack st;st.Init();st.Push(1);st.Push(2);st.Push(3);coutst.Top()endl;st.Destroy();return0;}为了区分成员变量一般习惯上成员变量会加一个特殊标识如成员变量前面或者后面加或者m开头注意C中这个并不是强制的只是一些惯例具体看公司的要求。int_day;int_month;int_year;C中struct也可以定义类C兼容c中struct的用法同时struct升级成了类明显的变化是struct中可以定义函数一般情况下我们还是推荐用class定义类。C升级struct升级成了类类里面可以定义函数struct名称就可以代表类型不需要typedef定义在类面的成员函数默认为inline1.2 访问限定符C一种实现封装的方式用类将对象的属性与方法结合在一块让对象更加完善通过访问权限选择性的将其接口提供给外部的用户使用。public修饰的成员在类外可以直接被访问protected和private修饰的成员在类外不能直接被访问访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止如果后面没有访问限定符作用域就到}即类结束。class定义成员没有被访问限定符修饰时默认为privatestruct默认为public。一般成员变量都会被限制为private/protected需要给别人使用的成员函数会放为public。1.3 类域类定义了一个新的作用域类的所有成员都在类的作用域中在类体外定义成员时需要使用作用域操作符指明成员属于哪个类域。#includeiostreamusingnamespacestd;classStack{public:voidInit(intn4);private:int*arr;intcapacity;inttop;};voidStack::Init(intn){arr(int*)malloc(sizeof(int)*n);if(arrNULL){perror(malloc);return;}capacityn;top0;}二、实例化2.1 实例化概念用类类型在物理内存中创建对象的过程称为类实例化出对象。类是对象进⾏⼀种抽象描述是⼀个模型⼀样的东西限定了类有哪些成员变量这些成员变量只是声明没有分配空间⽤类实例化出对象时才会分配空间classData{//不会开空间private:int_day;int_month;int_year;};一个类可以实例化出多个对象实例化出的对象占用实际的物理空间存储类成员变量,像一张设计图纸通过它可以建多个房子Stack st1;Stack st2;2.2 对象大小类实例化出的每个对象都有独立的数据空间所以对象中肯定包含成员变量大小不包含成员函数函数指针是不需要存储的函数指针是一个地址调用函数被编译成汇编指令[call地址]其实编译器在编译链接时就要找到函数的地址不是在运行时找对象中只存储成员变量C规定类实例化的对象也要符合内存对齐的规则与C语言结构体大小类似具体看这篇文章https://blog.csdn.net/2401_89538720/article/details/154124365?fromshareblogdetailsharetypeblogdetailsharerId154124365sharereferPCsharesource2401_89538720sharefromfrom_link注意当类为空或只有函数大小不为0而为1因为如果一个字节都不给怎么表示对象存在过呢所以这里给1字节纯粹是为了占位标识对象存在。三、this指针3.1 引入classDate{public:voidInit(intday,intmonth){_dayday;_monthmonth;}voidPrint(){cout_day _monthendl;}private:int_day;int_month;};intmain(){Date d1;Date d2;d1.Init(1,2);d2.Init(3,4);d1.Print();d2.Print();}Date类中有Init与Print两个成员函数函数体中没有关于不同对象的区分那当d1调用lnit和Print函数时该函数是如何知道应该访问的是d1对象还是d2对象呢编译器编译后类的成员函数默认都会在形参第一个位置增加一个当前类类型的指针叫做this指针。类的成员函数中访问成员变量本质都是通过this指针访问的//void Init( Date* const this,int day,int month)//{// this-_day day;// this-_month month;//}C规定不能在实参和形参的位置显示的写this指针编译时编译器会处理但是可以在函数体内显示使用this指针。voidInit(intday,intmonth){this-_dayday;this-_monthmonth;}3.2 易错点classA{public:voidPrint(){couthahaendl;}};intmain(){A*pnullptr;p-Print();return0;}该程序不会报错因为nullptr存放在this指针里面没有对其解引用classA{public:voidPrint(){couthahaendl;coutaendl;}private:inta;};intmain(){A*pnullptr;p-Print();return0;}这种会报错因为this-a对空指针解引用了补充 this指针存在内存栈上VS存放在寄存器上频繁调用四、C和C语言以C和c语言实现Stack对比为例4.1 分析C中数据和函数都放到了类里面通过访问限定符进行了限制不能再随意通过对象直接修改数据C中有一些相对方便的语法比如lnit给的缺省参数会方便很多成员函数每次不需要传对象地址因为this指针隐含的传递了方便了很多使用类型不再需要typedef用类名就很方便。4.2 代码实现C语言#includestdio.h#includestdlib.htypedefintSTDatatype;typedefstructSTack{STDatatype*arr;intcapacity;inttop;}ST;voidSTInit(ST*pst){pst-arrNULL;pst-capacitypst-top0;}voidSTPush(ST*pst,STDatatype x){if(pst-capacitypst-top){STDatatype newcapacitypst-capacity0?4:pst-capacity*2;STDatatype*ptr(STDatatype*)realloc(pst-arr,sizeof(STDatatype)*newcapacity);if(ptrNULL){perror(realloc);return;}pst-arrptr;pst-capacitynewcapacity;}pst-arr[pst-top]x;}intSTTop(ST*pst){returnpst-arr[pst-top-1];}voidSTDestroy(ST*pst){if(pst-arr!NULL){free(pst-arr);}pst-capacitypst-top0;}C#includeiostreamusingnamespacestd;typedefintSTDatatype;classSTack{public:voidInit(intn4){_arr(STDatatype*)malloc(sizeof(STDatatype)*n);_capacityn;_top0;}voidPush(STDatatype x){if(_capacity_top){STDatatype newcapacity_capacity0?4:_capacity*2;STDatatype*ptr(STDatatype*)realloc(_arr,sizeof(STDatatype)*newcapacity);if(ptrNULL){perror(realloc);return;}_arrptr;_capacitynewcapacity;}_arr[_top]x;}intTop(){return_arr[_top-1];}voidDestroy(){free(_arr);_arrnullptr;_top_capacity0;}private:STDatatype*_arr;STDatatype _capacity;STDatatype _top;};文章结语感谢你读到这里我是「键盘敲碎了雾霭」愿这篇文字帮你敲开了技术里的小迷雾 如果内容对你有一点点帮助不妨给个暖心三连吧点赞| ❤️收藏| ⭐关注听说三连的小伙伴代码一次编译过bug绕着走你的支持就是我继续敲碎技术雾霭的最大动力 小彩蛋/^ ^\ / 0 0 \ V\ Y /V / - \ / | V__) ||摸一摸毛茸茸的小狗赶走所有疲惫和bug我们下篇见 ✨