【C++】类和对象——类的引入、类的访问限定符、类的作用域、类的实例化、类的储存、this指针的引出和特性

news2024/11/27 6:43:08

文章目录

  • 1.类的引入
  • 2.类的访问限定符
  • 3.类的作用域
  • 4.类的实例化
  • 5.类的储存
  • 6.this指针
    • 6.1this指针的引出
    • 6.2this指针的特性

1.类的引入

  C++是在C的基础上加以扩展。

  在C语言中,我们想要让一个类型含有多种成员变量,我们使用结构体;而在C++中我们可以使用类和结构体。可以说在一般情况下类要优于结构体:

(1)结构体和类都可以包含一组数据成员,这些成员可以是不同的数据类型和集合类型。

(2)结构体和类都可以包含一组成员函数,这些函数可以操作数据成员和执行其他任务。

(3)类比结构体更具有抽象和封装特性,类中的数据成员和成员函数可以通过访问控制符private、protected、public来控制外部访问和使用。

(4)结构体可以进行基本操作,如赋值、比较和作为函数参数传递等。类继承了结构体的这些基本操作。同时,也可实现更多的高级操作,并具有更好的可维护性、可扩展性和数据隐私性。

(5)在C++中,结构体可以看作是一种类,而类可以扮演结构体的角色。

  在C++中,类是面向对象编程的基础,它提供了许多方便的编程手段,包括封装、继承、多态和动态内存分配等,使得程序员能够更方便地开发大型、复杂的应用程序。因此,总体来说,相比结构体,类更加灵活、丰富和易用,并且有更多更复杂的应用场景。

用C++定义一个学生类:

#include <string>
using namespace std;

// 定义学生类
class Student {
    string name;
    int age;
    double score;
};

2.类的访问限定符

  C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。

  在C++中,类的成员可以使用三种不同的访问限定符来控制成员的可访问性,它们分别是:

(1)private(私有访问限定符):类的私有成员只能被类中的其他成员函数访问,不能被类外的任何函数或对象直接访问。

(2)protected(保护访问限定符):类的保护成员可以被类中的成员函数和派生类中的成员函数访问,但不能被类外的任何函数或对象直接访问。

(3)public(公共访问限定符):类的公共成员可以被类中的成员函数、派生类中的成员函数以及类外的任何函数或对象直接访问。

在这里插入图片描述

【访问限定符说明】

(1)public修饰的成员在类外可以直接被访问。

(2)protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)。

(3)访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。

(4)如果后面没有访问限定符,作用域就到 } 即类结束。

(5)class的默认访问权限为private,struct为public(因为struct要兼容C)。

注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别

用C++定义一个学生类:

#include <string>
using namespace std;

// 定义学生类
class Student {
private:
    string name;
    int age;
    double score;
public:
    Student(string n, int a, double s);  // 构造函数
    string get_name();
    void set_name(string n);
    int get_age();
    void set_age(int a);
    double get_score();
    void set_score(double s);
    void display();
};

3.类的作用域

  类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域。

  C++中,类的作用域类似于命名空间。在C++中,类的作用域可以分为两个部分:

(1)类的定义部分:类的定义部分包括在类声明中的所有内容,例如成员变量、成员函数、访问限定符等。这些内容在类外不可见,在类内部可以直接访问,只有在类外使用类名限定符才能访问。

(2)类的成员函数定义部分:类的成员函数定义部分包括在类外定义的所有成员函数。在类声明中声明的成员函数只是一个函数声明,必须在类外部定义成员函数。在函数定义中,可以直接使用类名限定符访问类的成员变量和成员函数,例如className::memberName。


用C++定义一个学生类:

#include <string>
using namespace std;

// 定义学生类
class Student {
private:
    string name;
    int age;
    double score;
public:
    Student(string n, int a, double s);  // 构造函数
    string get_name();
    void set_name(string n);
    int get_age();
    void set_age(int a);
    double get_score();
    void set_score(double s);
    void display();
};

// 构造函数的定义
Student::Student(string n, int a, double s) {
    name = n;
    age = a;
    score = s;
}

// 学生姓名访问函数
string Student::get_name() {
    return name;
}

// 学生姓名设置函数
void Student::set_name(string n) {
    name = n;
}

// 学生年龄访问函数
int Student::get_age() {
    return age;
}

// 学生年龄设置函数
void Student::set_age(int a) {
    age = a;
}

// 学生成绩访问函数
double Student::get_score() {
    return score;
}

// 学生成绩设置函数
void Student::set_score(double s) {
    score = s;
}

// 显示学生信息
void Student::display() {
    cout << "姓名:" << name << endl;
    cout << "年龄:" << age << endl;
    cout << "成绩:" << score << endl;
}

4.类的实例化

  用类类型创建对象的过程,称为类的实例化。

(1)类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它;比如:入学时填写的学生信息表,表格就可以看成是一个类,来描述具体学生信息。

(2)一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量

(3)类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间。
在这里插入图片描述


用C++定义一个学生类:

#include <string>
using namespace std;

// 定义学生类
class Student {
private:
    string name;
    int age;
    double score;
public:
    Student(string n, int a, double s);  // 构造函数
    string get_name();
    void set_name(string n);
    int get_age();
    void set_age(int a);
    double get_score();
    void set_score(double s);
    void display();
};

// 构造函数的定义
Student::Student(string n, int a, double s) {
    name = n;
    age = a;
    score = s;
}

// 学生姓名访问函数
string Student::get_name() {
    return name;
}

// 学生姓名设置函数
void Student::set_name(string n) {
    name = n;
}

// 学生年龄访问函数
int Student::get_age() {
    return age;
}

// 学生年龄设置函数
void Student::set_age(int a) {
    age = a;
}

// 学生成绩访问函数
double Student::get_score() {
    return score;
}

// 学生成绩设置函数
void Student::set_score(double s) {
    score = s;
}

// 显示学生信息
void Student::display() {
    cout << "姓名:" << name << endl;
    cout << "年龄:" << age << endl;
    cout << "成绩:" << score << endl;
}

// 主函数
int main() {
    // 实例化一个学生对象并设置其属性
    Student stu("Tom", 18, 90.5);

    // 显示学生信息
    stu.display();

    // 修改学生属性
    stu.set_name("Jack");
    stu.set_age(19);
    stu.set_score(88.5);

    // 再次显示学生信息
    stu.display();

    return 0;
}

5.类的储存

  C++ 中的类对象是存储在计算机内存中的,存储方式取决于具体的编译器、操作系统和硬件等因素。一般来说,类对象在内存中的存储是连续的,其中包括成员变量(也称为类数据成员)和成员函数(也称为类成员函数)。

  成员变量存储的位置会根据其访问修饰符的不同而分为公有、私有或保护成员。对于公有成员变量,可以通过对象或者指向对象的指针直接访问。而私有成员变量和保护成员变量只能由类内部的成员函数通过 this 指针来访问,其它方式都无法直接访问。

  成员函数存储的位置和成员变量不同:类的成员函数是在类外定义的,因此它们不会占用对象存储空间。不同的成员函数有不同的调用方式:对于普通成员函数,有固定的传参方式,会在函数内部调用 this 指针指向的对象;而静态成员函数则不需要通过对象调用,因此没有 this 指针,并且可以被所有对象和类共享。

  需要注意的是,在类中定义的静态成员变量在内存中只有一份,不属于对象而是属于类本身。所以,无论有多少个类的对象都只会有一个静态成员变量存储空间。

  总的来说,类存储方式是由编译器、操作系统和硬件等多种因素共同决定的,并且不同编译器和平台的存储方式可能存在差异。但是,我们可以通过了解类的访问修饰符和成员函数等基本特性,来更好地理解类在内存中的存储原理以及如何使用和管理类对象的内存。

在这里插入图片描述

结构体内存对齐规则

// 类中既有成员变量,又有成员函数
class A1 {
public:
 void f1(){}
private:
 int _a;
};
// 类中仅有成员函数
class A2 {
public:
 void f2() {}
};
// 类中什么都没有---空类
class A3
{};

sizeof(A1) : ___4___  sizeof(A2) : ___1___  sizeof(A3) : ___1___

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

6.this指针

6.1this指针的引出

先定义一个日期类:

class Date
{ 
public:
 void Init(int year, int month, int day)
 {
	_year = year;
 	_month = month;
 	_day = day;
 }
 
 void Print()
 {
	cout <<_year<< "-" <<_month << "-"<< _day <<endl;
 }
 
private:
	int _year; // 年
	int _month; // 月
	int _day; // 日
	int a;
};

int main()
{
	Date d1, d2;
	d1.Init(2022,1,11);
	d2.Init(2022, 1, 12);
	d1.Print();
	d2.Print();
	return 0;
}

对于上述类,有这样的一个问题:

Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用 Init 函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?

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

6.2this指针的特性

  在 C++ 中,this 是一个指向当前对象的指针,它有以下特性:

(1)this指针的类型:类类型* const,即成员函数中,不能给this指针赋值。

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

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

(4)this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。
在这里插入图片描述

1.this指针可以为空吗?
  this指针是可以为空指针的,但是不能解引用。通常我们不应该让this指针为空指针。

2.this指针存在哪里?

   this指针存放在调用函数的栈帧里面,VS下对this指针进行了优化,存放在寄存器ECX里面。

  需要注意的是,this 指针是常量指针,它指向的地址不能被修改。因此,在成员函数中不能直接修改 this 指针的指向,否则会导致编译错误。另外,在一些特殊场合下,this 指针的值可能会被修改(如使用 const_cast 显式地转换掉 const 属性),但这样做通常是不被推荐的,因为会破坏对象的封装性和安全性。

这些就是C++中类和对象的简单介绍了😉
如有错误❌望指正,最后祝大家学习进步✊天天开心✨🎉

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Doris节点扩容及数据表

扩容和缩容 上篇文章简单讲了doris的安装&#xff0c;本章分享的是doris中fe和be节点的扩容缩容以及doris的数据表1、FE 扩容和缩容 使用 MySQL 登录客户端后&#xff0c;可以使用 sql 命令查看 FE 状态&#xff0c;目前就一台 FE mysql -h linux -P 9030 -uroot -p mysql&…

python+django乡村居民数据的可视化平台

本论文主要论述了如何使用Django框架开发一个乡村振兴数据的可视化平台 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述乡村振兴数据的可视化平台的当前背景以…

拼多多二面,原来是我对自动化测试的理解太浅了

如果你入职一家新的公司&#xff0c;领导让你开展自动化测试&#xff0c;作为一个新人&#xff0c;你肯定会手忙脚乱&#xff0c;你会如何落地自动化测试呢&#xff1f; 01 什么是自动化 有很多人做了很长时间的自动化但却连自动化的概念都不清楚&#xff0c;这样的人也是很悲…

Android之 MVC到MVVM架构发展和封装

一 简介 1.1 软件架构发展趋势是解耦&#xff0c;即分离数据层和视图层&#xff0c;使得数据层专注于业务的数据和逻辑处理。从而提高代码的可读可编辑效率&#xff0c;提高团队协作能力&#xff0c;项目的生产能力&#xff0c;降低后期维护成本。 1.2 Android架构发展MVC -…

计算机组成原理实验四 微程序控制器实验报告

我班算是几乎最后一个做实验的班级了&#xff0c;报告参考了一些朋友提供的数据加上一些自己的主观拙见&#xff0c;本人水平有限加之制作仓促难免有错误&#xff0c;望大家批评指正。 4.1 微程序控制器实验 一、实验目的 (1) 掌握微程序控制器的组成原理。 (2) 掌握微程序的…

【蓝桥杯计算思维题】少儿编程 蓝桥杯青少组计算思维真题及详细解析第5套

少儿编程 蓝桥杯青少组计算思维真题及详细解析第5套 1、北京冬奥会经历 17( ),中国体育代表团收获的金牌数和奖牌数均创历史新高 A、年 B、月 C、天 D、小时 答案:C 考点分析:主要考查小朋友们对时事的了解,北京冬奥会总共经历了17天,所以答案C 2、下面图形的周长是…

Python系列模块之标准库json详解

感谢点赞和关注 &#xff0c;每天进步一点点&#xff01;加油&#xff01; 目录 一、Json介绍 二、JSON 函数 2.1 json.dumps 2.2 json.loads 2.3 实战案例&#xff1a;钉钉消息发送 一、Json介绍 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它使得人们…

2023年21个最佳的Ruby测试框架

作者 | Veethee Dixit 测试人员总是在寻找最好的自动化测试框架&#xff0c;它能提供丰富的功能&#xff0c;并且语法简单、兼容性好、执行速度快。如果你选择将Ruby与Selenium结合起来进行web测试&#xff0c;那么可能需要搜索基于Ruby的测试框架进行web应用程序测试。 Ruby…

【Python】函数式编程第二弹

知识目录 一、写在前面✨二、最小公倍数三、移除数字四、总结撒花&#x1f60a; 一、写在前面✨ 大家好&#xff01;我是初心&#xff0c;希望我们一路走来能坚守初心&#xff01; 今天跟大家分享的文章是 Python函数式编程第二弹&#xff0c;再次以两个简单的例子带大家更好…

selenium UI自动化中文件上传的两种方式

前言 文件上传是自动化中很常见的一个功能&#xff0c;那么对于文件上传你又有多少了解呢&#xff1f;请往下看 1、被测产品中文件上传的功能非常普遍&#xff0c;一般情况下需要将准备好的文件放在预定的路径下&#xff0c;然后在自动化测试的脚本中&#xff0c;去预置的路径…

国内可以免费使用的GPT

一、wetab新标签页 教程&#xff1a;https://diwlwltzssn.feishu.cn/docx/MnHhdvxATomBnMxfas2cm8wWnVd 装GPT界面&#xff1a;https://microsoftedge.microsoft.com/addons/detail/wetab%E5%85%8D%E8%B4%B9chatgpt%E6%96%B0%E6%A0%87%E7%AD%BE%E9%A1%B5/bpelnogcookhocnaokfp…

TeX Live和TeX studio安装

最近想要研究一下Letex怎么写论文&#xff0c;然后就查阅资料了解了一下&#xff0c;先安装上两个软件&#xff0c;怎么用在研究研究&#xff0c;这里记录一下软件安装过程&#xff0c;方便以后查阅。 TeX Live和TeX studio安装 Latex介绍TexLive安装下载TexLive的安装包安装Te…

C++知识第三篇之继承

C继承 继承是面向对象编程的重要特征&#xff0c;是对类设计层次的复用 文章目录 C继承一.介绍1.继承定义2.继承方式3.class与struct 二.作用域1.成员变量2.成员函数 三.赋值转换1.给基类对象赋值2.给基类对象指针赋值 四.派生类的默认函数五. 其他1.友元2.静态 六.继承1.单继承…

Android车载学习笔记1——车载整体系统简介

一、汽车操作系统 汽车操作系统包括安全车载操作系统、智能驾驶操作系统和智能座舱操作系统。 1. 安全车载操作系统 安全车载操作系统主要面向经典车辆控制领域&#xff0c;如动力系统、底盘系统和车身系统等&#xff0c;该类操作系统对实时性和安全性要求极高&#xff0c;生态…

VCSA 和ESXi 6.7.0版本升级

1. VCSA升级步骤 1&#xff09;指定升级包的位置 software-packages stage --iso (如果是从vmware下载补丁&#xff0c;使用CD/DVD来映射ISO映像) 或 software-packages stage --url https://vapp-updates.vmware.com/vai-catalog/valm/vmw/8d167796-34d5-4899-be0a-6daade400…

Yolov8涨点神器:注意力机制---多头上下文集成(Context Aggregation)的广义构建模块,助力小目标检测,暴力涨点

🏆🏆🏆🏆🏆🏆Yolov8魔术师🏆🏆🏆🏆🏆🏆 ✨✨✨魔改网络、复现前沿论文,组合优化创新 🚀🚀🚀小目标、遮挡物、难样本性能提升 🍉🍉🍉定期更新不同数据集涨点情况 2.Context Aggregation介绍 论文:https://arxiv.org/abs/2106.01401 仅…

落地页设计的营销心理学(二)

作为一个营销落地页的设计者&#xff0c;最关注的问题&#xff1a;怎么样设计才能让我的落地页有转化&#xff1f; 当然这可能有很多影响因素。但是&#xff0c;你有没有想过在用户打开落地页时&#xff0c;运用心理学概念留住他们&#xff0c;促使他们完成留资、下载、购买等动…

听我一句劝,不要去外包,干了三年,废了....

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

Python实战基础12-闭包

1、函数的嵌套调用 def testB():print(-------testB start------)print(这里是testB函数执行的代码……)print(-------testB end ------)def testA():print(-----testA start-----)testB()print(-----testA end------) testA() 运行结果&#xff1a; 总结&#xff1a; 一个函…

PoseiSwap 参赛,参与斯坦福、Nautilus等联合主办的 Hackathon 活动

近日&#xff0c;由 Stanford Blockchain Accelerator、Zebec Protocol、 Nautilus Chain、Rootz Lab 共同主办的“ Boundless Hackathon Stanford ” 主题的黑客松活动&#xff0c;目前已接受报名。该活动旨在帮助更多的优质开发者参与到 Web3 世界的发展中&#xff0c;推动链…