C++之类(持续更新)

1、类的基础知识点

1.1、类和对象

        和C中的结构体不同,在C++类中不仅可以定义变量,也可以定义函数。【在C++结构体中也可以定义变量和函数,但是一般情况下都使用类】。

        类的成员属性默认都是private;结构体的成员属性默认都是public。

class student
{
public:// 共有成员(外部接口,可被使用该类的所有代码所使用的)student();~student();void set_age(int age_t);
private:// 私有成员(只允许本类中的函数访问,而类外部的任何函数都不允许访问)char name[50];int age;
protected:// 保护成员(与private类似,差别表现在继承与派生时)
};

        类中的元素称为类的成员;类中的数据称为类的属性或者成员变量;类中的函数称为类的方法或者成员函数。

1.2、类中成员函数定义

(1)声明和定义都放在类体中

// .h文件中
class student
{
public:// 共有成员(外部接口,可被使用该类的所有代码所使用的)student();~student();void set_age(int age_t){age = age_t;}
private:// 私有成员(只允许本类中的函数访问,而类外部的任何函数都不允许访问)char name[50];int age;
protected:// 保护成员(与private类似,差别表现在继承与派生时)
};

(2)声明和定义分离

// .h文件中
class student
{
public:// 共有成员(外部接口,可被使用该类的所有代码所使用的)student();~student();void set_age(int age_t);
private:// 私有成员(只允许本类中的函数访问,而类外部的任何函数都不允许访问)char name[50];int age;
protected:// 保护成员(与private类似,差别表现在继承与派生时)
};
// .cpp文件中
void student::set_age(int age_t)
{age = age_t;
}

1.3、类的作用域

        C++类重新定义了一个作用域,类的所有成员都在类的作用域中。在类外使用成员时,需要使用 ::(作用域解析符)来指明成员属于哪个类。

1.4、实例化

        用类去创建对象的过程,称为类的实例化。类只声明了类有哪些成员,而并没有为成员分配内存空间。一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量

        类是对象的抽象和概括,而对象是类的具体和实例。

1.5、类对象的存储方式

C++程序占用的内存通常分为四个区:

        代码区(code area):存放着程序的二进制代码,由操作系统管理。

        全局区(static area):存放全局变量,静态变量,以及常量(字符常量和const修饰的全局变量)。

        栈区(stack area):存放所有的局部变量,其空间分配释放由编译器管理,当函数结束,局部变量自动被释放。

        堆区(heap area):存放所有动态开辟的变量,其空间分配释放由程序员管理。

类对象存储如下:

在类定义时:

        类的成员函数是被放在代码区。

        类的静态成员变量是存储在静态区的,即实例化的对象并不包括静态变量的创建。

        类的静态成员变量,在类的实例化过程中才在栈区或者堆区为其分配内存,是为每个对象生成一个拷贝,所以它是属于对象的。

#include <iostream>
using namespace std;class student_1
{
public:void set_age(int age_t);
private:char name[50];int age;static char aa[8];
}std_1;class student_2
{
public:private:char name[50];int age;
}std_2;class student_3
{
}std_3;int main(int argc, char argv[])
{cout << "  " << sizeof(std_1) << endl;cout << "  " << sizeof(std_2) << endl;cout << "  " << sizeof(std_3) << endl;return 0;
}

输出:

56
56
1

结论:

        一个类的大小,实际就是该类中“成员变量”之和,当然也要进行内存对齐,注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类。

注意:

        这里的成员变量之和并不是简单的字节数相加,而是还要遵循内存对齐规则。

1.6、this指针


#include <iostream>
using namespace std;class student
{
public:void set_id(int grade_id__t, int class_id_t);void display_id_0(){cout << "grade_id: " << grade_id << ", class_id: " << class_id << endl;}void display_id_1(){cout << "grade_id: " << this->grade_id << ", class_id: " << this->class_id << endl;}
private:char name[50];int age;int grade_id;int class_id;
};void student::set_id(int grade_id__t, int class_id_t)
{grade_id = grade_id__t;class_id = class_id_t;
}int main(int argc, char argv[])
{student std_1, std_2;std_1.set_id(10, 11);std_2.set_id(101, 34);std_1.display_id_0();std_1.display_id_1();std_2.display_id_0();std_2.display_id_1();return 0;
}

结果为:

grade_id: 10, class_id: 11
grade_id: 10, class_id: 11
grade_id: 101, class_id: 34
grade_id: 101, class_id: 34

问题一:

        对于上述程序,std_1和std_2各自有不同的内存空间,而成员函数set_id中却并没有指定要对哪一个对象的成员进行操作,那么当std_1调用时函数是如何知道操作的对象是哪一个呢?

答:

        C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数”增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

this指针的特性:

        this指针的类型:类的类型* const,this在函数体内不可修改。

        只能在“成员函数”的内部使用。

        this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参,所以对象中不存储this指针。

        this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。

问题二:

        this指针的存储位置在哪里?

答:

        临时变量都是存储在栈上的,因此this指针作为形参,存储在栈区。

问题三:

        this指针可以为空指针吗?

答:

        this指针可以为空指针,但切忌通过nullptr去访问指向的数据。


#include <iostream>
using namespace std;class student
{
public:void set_id(int grade_id__t, int class_id_t);void display_id(){cout << "grade_id: " << grade_id << ", class_id: " << class_id << endl;}void display(){cout << "grade_id and class_id" << endl;}
private:char name[50];int age;int grade_id;int class_id;
};void student::set_id(int grade_id__t, int class_id_t)
{grade_id = grade_id__t;class_id = class_id_t;
}int main(int argc, char argv[])
{student *std_1 = nullptr;std_1->display();         // 执行成功std_1->display_id();      // 执行失败return 0;
}

        成员函数display()执行成功,而成员函数display_id()执行失败。首先nullptr地址我们是没有访问权限的,非法访问会使程序崩溃。

        display()执行成功,因为访问的是成员函数,成员函数不在对象内,就不会对指针解引用,std_1->的作用仅仅是指明了函数的类域,而函数内也没有使用到this指针,所以不会报错。

        display_id()执行失败,是因为在打印的时候调用了成员变量grade_id和class_id,而std_1又指向了nullptr,相当于访问了nullptr地址处的数据,因此程序崩溃。

2、

3、

4、

5、

End、结语

感谢参考的文档;参考的文档太多,不做一一列举。

感谢大家提供的建议;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/544413.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VLC抓取m3u8视频

前言 最近想看一些网络视频&#xff0c;但是很多时候网页上是m3u8推流的&#xff0c;如果在线看&#xff0c;速度又慢&#xff0c;所以就想下载下来&#xff0c;就想到了VLC的推流&#xff0c;转换能力&#xff0c;查阅资料&#xff0c;加上实践&#xff0c;总结心得。 设置中…

用 Visual Studio 调试器中查看内存中图像

返回目录&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 前一篇&#xff1a;OpenCV4.9.0在windows系统下的安装 后一篇&#xff1a; ​警告 本教程可以包含过时的信息。 Image Watch 是 Microsoft Visual Studio 的插件&#xff0c;可用于在调…

简易版 RPC 框架实现 2.0 -netty实现

这一篇理解如果有难度&#xff0c;可能对netty不是很理解&#xff0c; 可以关注我netty专栏&#xff0c;还有另外一篇&#xff1a; 用 Netty 自己实现简单的RPC&#xff0c; 这一篇是学习netty的时候写的&#xff0c;更倾向于分析netty相关的知识&#xff0c; 今天我是学习dubb…

物联网 3.15日 | 2024年中国七大 IoT 物联网云平台价格对比

随着 中国电信天翼 CTWing 物联网平台正式开始收费&#xff0c;国内物联网平台云产品发展进入成熟期&#xff0c;越来越多企业选择云厂商提供的物联网PaaS服务&#xff0c;以降低运营成本&#xff0c;缩短业务上线周期&#xff0c;释放运维的人力&#xff0c;按需付费动态扩容。…

MyBatis plus自动生成代码

1.pom文件配置 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version> </dependency> <dependency><groupId>com.baomidou</groupId>…

HarmonyOS NEXT应用开发—组件堆叠

介绍 本示例介绍运用Stack组件以构建多层次堆叠的视觉效果。通过绑定Scroll组件的onScroll滚动事件回调函数&#xff0c;精准捕获滚动动作的发生。当滚动时&#xff0c;实时地调节组件的透明度、高度等属性&#xff0c;从而成功实现了嵌套滚动效果、透明度动态变化以及平滑的组…

layui table列表重载后保持进度条位置不变

使用layui的table表格组件时&#xff0c;当我们操作了某行的修改后&#xff0c;刷新了页面&#xff0c;进度条则跳回到最上面。 除了layui高版本应该内置有方法解决了此问题&#xff0c;但是低版本需要另外想办法解决。 具体解决方式如下&#xff1a; 1.在编辑操作成功前&am…

Artemis Finance引领Metis流动性质押,并启动积分空投活动

在以太坊可扩展性解决方案中&#xff0c; Optimism、Arbitrum等Layer2链主要面临两个问题&#xff1a;欺诈/有效性证明以及去中心化排序器Sequencers。在实际的发展过程中&#xff0c;Optimism或Arbitrum等Layer2链仍然侧重于在欺诈证明和有效性证明方面进行努力&#xff0c;在…

springboot爱看漫画小程序的设计与实现

摘 要 相比于以前的传统手工管理方式&#xff0c;智能化的管理方式可以大幅降低爱看漫画的运营人员成本&#xff0c;实现了爱看漫画的标准化、制度化、程序化的管理&#xff0c;有效地防止了爱看漫画的随意管理&#xff0c;提高了信息的处理速度和精确度&#xff0c;能够及时、…

C# 面试题及答案整理,最新面试题

解释C#中的垃圾回收机制是如何工作的。 C#中的垃圾回收&#xff08;GC&#xff09;机制是CLR&#xff08;公共语言运行时&#xff09;的一部分&#xff0c;负责自动管理内存&#xff0c;具体工作原理如下&#xff1a; 1、分代回收&#xff1a; GC将对象分为0代、1代和2代三代…

十四、自回归(AutoRegressive)和自编码(AutoEncoding)语言模型

参考自回归语言模型&#xff08;AR&#xff09;和自编码语言模型&#xff08;AE&#xff09; 1 自回归语言模型&#xff08; AR&#xff09; 自回归语言模型&#xff08;AR&#xff09;就是根据上文内容&#xff08;或下文内容&#xff09;预测下一个&#xff08;或前一个&…

wsl2+docker-desktop环境,个别命令卡住问题

*在win11本地搭建了一套开发环境&#xff0c;之前一直用得很舒服&#xff0c;最近发现些问题&#xff0c;查了几天&#xff0c;记录下解决方案。*环境信息&#xff1a; 问题&#xff1a;在wsl2的ubuntu虚拟机中&#xff0c;有时会出现个别命令运行卡住不返回 像上图&#xff0…