【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)

news2024/12/26 11:26:36

🌟🌟作者主页:ephemerals__

🌟🌟所属专栏:C++

目录

前言

一、类的概念及定义

1. 类的定义格式 

2. 访问限定符

二、类域

三、类的实例化--对象

1. 实例化的概念

2. 对象的内存大小

四、this指针

总结


前言

        c++是一种支持面向对象编程(OOP)的语言,而在面向对象编程当中,类和对象是核心概念,理解类和对象是学习面向对象编程的基石。面向对象编程是一种编程范式,它使用“类”来定义对象的属性和方法,完成对软件的设计。掌握类和对象的概念及其相互关系,对于深入理解并有效应用面向对象编程至关重要。

一、类的概念及定义

        类的本质是一种自定义类型,是定义对象模板的蓝图或者结构。它制定了对象可以包含的数据以及该对象可以执行的操作。在某种程度上,c++中的类可以认为是c语言结构体的升级版,不仅可以在其中定义成员变量,也可以定义成员函数,用于对成员变量进行访问或操作。

1. 类的定义格式 

      接下来我们尝试定义一个类:

class MyClass
{
	void fun1()
	{
		//...
	}
	void fun2()
	{
		//...
	}
	int _x;
	float _y;
};

以上代码当中:

1. class 是定义类的关键字,Myclass类名,{} 中的内容是类的主体fun1和fun2是类的成员函数_x 和_y 是类的成员变量

2. 注意定义最后的分号不能省略。

 注意事项:

1.为了防止命名冲突,类的成员变量在创建时一般会在变量名前加上一个特殊的标识符,例如_x,_y。

2.类的成员函数默认具有标签inline

        在c++当中,struct也可以用于定义类,与c语言不同的是,strcut当中可以定义函数,并且类的类型名不需要再带struct

2. 访问限定符

        c++中有三种访问限定符,用于对类成员的访问权限进行限制,它们分别是:

public(公有):使得被修饰的成员可以在类的外部被访问和修改

protected(保护):被修饰的成员不可在类外部进行访问,但可以在子类当中访问

private(私有):对于被修饰的成员,无论是在类外还是在子类中,都无法访问及修改

一般情况下,我们会对类中的成员变量修饰为private,防止它被外部修改;成员函数修饰为public,便于外部进行方法的调用。

注意:class定义的类当中,如果成员没有被这三种访问限定符修饰,则这些成员默认被private修饰;而struct中的成员默认被public修饰。

接下来,我们简单使用一下这些访问限定符:

#include <iostream>
using namespace std;

class MyClass
{
public:
	void fun1()
	{
		//...
	}

	void fun2()
	{
		//...
	}
private:
	int _x;
	float _y;
};


int main()
{
	//创建一个MyClass类对象
	MyClass a;
	a.fun1();//公有的,可以在外部访问
	a._x = 10;//私有成员,不可访问,报错
	return 0;
}

        我们在使用访问限定符时:在其后加上一个冒号,表示从此处开始到下一个访问限定符或者类结束的位置之间的所有成员都被修饰。例如,这里的fun1、fun2函数被修饰为public;_x、_y被修饰为private

        访问限定符不仅是面向对象编程的特性之一——封装的具体实现,也促进了软件设计的质量、规范性、可维护性和安全性。它们是面向对象编程中不可或缺的一部分。

二、类域

        既然学到了类,那就不得不提及类域了。我们都知道,c++一共有四大域:函数局部域、全局域、命名空间域和类域。而我们之前在类中定义的成员函数和成员变量,就属于类域。当我们在类外对类中的成员进行定义时,就需要用域限定运算符“ : : ”。举个例子:

class MyClass
{
public:
	void fun();//方法的声明

private:
	int _m;
};

void MyClass::fun()//方法的定义,要使用域限定运算符表明该方法所在的类域
{
	//...
}

那么,为什么要使用域限定运算符来表明类域呢?因为类域影响的是编译器的查找规则。如果fun函数没有声明类域,那么编译器就会从全局域去查找该函数的声明。此时如果fun函数有涉及对成员变量_m的操作,编译器从全局域找不到_m,就会发生报错

三、类的实例化--对象

1. 实例化的概念

         与结构体的定义和创建类似,当我们定义了一个类以后,就可以用这个类在内存中创建出一个对象。所谓对象,指的就是根据类创建出的“变量”。而根据类创建对象的过程,叫做类的实例化,我们在内存中创建出的每一个对象都是类的实例。

我们写一段代码体现类的实例化:

#include <iostream>
using namespace std;

//类的定义
class MyClass
{
public:
	void fun() 
	{
		//...
	}
private:
	int _x;
};

int main()
{
	MyClass a;//类的实例化,创建一个对象叫a
	return 0;
}

在上述代码中,我们对类进行定义时,编译器并没有为其开辟内存空间就像是造房子的图纸,类就是一个模板,而对象则是根据这个模板建造出的“房子”,创建对象时才会分配内存空间

2. 对象的内存大小

        既然创建对象时才分配内存空间,那么对象所占内存空间的大小是多少呢?

首先我们写一段程序,用sizeof来计算对象的内存大小:

#include <iostream>
using namespace std;

class X
{
public:
	void fun() 
	{
		//...
	}
private:
	int _x;
};

int main()
{
	X x;
	cout << sizeof(x) << endl;
	return 0;
}

运行结果:

可以看到,对象x所占空间是4个字节。从代码当中得知,这个类中包含一个函数fun和一个整形变量_x,而整形的大小是4个字节,所以说对于对象而言,成员变量的内存是包含在其中的,而成员函数不在对象当中存储,而是在代码段当中。其次,c++规定,对象的成员变量才存储时要符合结构体的内存对齐规则

规则如下:

1.结构体的第一个成员对齐到和结构体的起始地址的偏移量为0的地址处,也就是说第一个成员的偏移量记为0。

2.其他的成员要对齐到该成员的对齐数整数倍的地址处。

对齐数:编译器默认对齐数与该成员内存大小的较小值;在VS环境中,默认对齐数是8;linux系统中,没有默认对齐数,对齐数就是该成员内存大小)

3.结构体的总大小为结构成员中最大的对齐数的整数倍

4.嵌套结构体的情况:则内层的结构体要对齐到自己成员中最大对齐数的整数倍处;结构体的总大小为结构成员中最大对齐数的整数倍(结构成员包含内层结构体的结构成员)。

当类中仅有成员函数或者空类的情况:

#include <iostream>
using namespace std;

class A
{
	void fun()
	{
		//...
	}
};

class B
{

};

int main()
{
	cout << sizeof(A) << endl;
	cout << sizeof(B) << endl;
	return 0;
}

运行结果:

当类中只有成员函数或者类为空类时,其所创建的对象大小为1字节,纯属占位作用

四、this指针

        首先来看一段代码:

#include <iostream>
using namespace std;

class MyClass
{
public:
	MyClass(int a = 0, float b = 0, char c = 0)//构造函数,用于初始化对象的成员变量,后续会给大家介绍
	{
		_a = a;
		_b = b;
		_c = c;
	}
	void Print()
	{
		cout << _a << endl;
		cout << _b << endl;
		cout << _c << endl;
	}
private:
	int _a;
	float _b;
	char _c;
};

int main()
{
	MyClass m = { 1,5.5,'w' };
	m.Print();
}

运行结果:

以上程序中,我们首先用MyClass创建了一个对象m,并且对其进行了初始化。之后,我们打印了一下其中三个成员变量的值。这里不难发现,Print函数是没有参数的。那既然没有参数,那么编译器是怎么知道要打印的是哪个对象的成员变量呢?

        实际上,这里的Print函数的参数的第一个位置,存在一个隐含的this指针

当我们调用对象的成员函数时,本质是将该对象的地址赋值给this指针,隐含的this指针总是指向该对象,不可改变。也就是说,该函数调用当中的this指针指向的是对象m。所以它的本质是通过隐含的this指针,就访问到了对象m的成员。

要注意:

1. 在函数的实参和形参中,这个this指针会自动在参数第一个位置生成,我们不能显示地写出来;但是在函数体内我们可以使用this指针。

2. this指针只能在成员函数内部使用。

3. this指针只是一个形参,并不存储在对象当中。

        this指针的用处:

1. 当我们需要使成员函数返回该对象的地址,就可以return this;
2. 当函数内的局部变量与类的成员变量名发生冲突时,就可以在类成员前加上this->,便于区分。

小练习:

1. 以下代码的运行结果是?

#include <iostream>
using namespace std;

class MyClass
{
public:
	void Print()
	{
		cout << "hehe" << endl;
	}
private:
	int _a;
};

int main()
{
	MyClass* a = nullptr;
	a->Print();
}

答案:

正常运行,打印“hehe”。原因是:这里创建类指针a,并且调用函数Print。可以看到程序中虽然使用了“->”,但是并没有对空指针a进行解引用,本质是将a传递给了形参this指针。而函数当中并没有访问成员变量,只是打印了“hehe”,所以不会发生问题,程序正常运行。

2. 以下代码的运行结果是:

#include <iostream>
using namespace std;

class MyClass
{
public:
	void Print()
	{
		cout << _a << endl;
	}
private:
	int _a;
};

int main()
{
	MyClass* a = nullptr;
	a->Print();
}

答案:

运行崩溃。和上一道题相同,本质也是将a传给了形参this,但是函数内部却访问了成员变量_a,我们都知道_a本质是由this指针解引用访问到的,但是此时的形参this是空指针,所以就出现了对空指针解引用的问题,运行崩溃。

总结

        今天,我们初入了c++类和对象的大门,学习了类的概念及定义、类实例化出对象,以及this指针的概念及作用。学习并理解这些知识,对于我们理解面向对象编程的特性之一--封装有很大帮助。如果你觉得博主讲的还不错,就请留下一个小小的赞在走哦,感谢大家的支持❤❤❤

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

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

相关文章

Vue——认识day02

此处接上一篇文章Vue——初识Vue开始&#xff0c;欢迎大家。 目录 1.MVVM模型 2.Object.defineproperty方法 3.数据代理简介 4.Vue中的数据代理 总结 1.MVVM模型 MVVM模型是一种软件架构模式&#xff0c;用于将用户界面&#xff08;View&#xff09;&#xff0c;业务逻辑&…

牛客周赛 Round 35 (A~G)

本次A~D较为简单&#xff0c;E是一道很好的构造题&#xff0c;FG主要就是考察组合数和约数个数 A.小红的字符串切割 思路 &#xff1a;签到题 void solve() {string s;cin>>s;int lens.size();cout<<s.substr(0,len/2)<<endl<<s.substr(len/2); }B.小…

搭建面向切面编程项目

此项目在整合Mybatis基础上修改&#xff0c;可参考主页的整合Mybatis文章 注解版本 第一步 引入maven坐标 <!-- 切面编程所需jar包--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId>…

Chapter 04 Vue指令(下)

欢迎大家订阅【Vue2Vue3】入门到实践 专栏&#xff0c;开启你的 Vue 学习之旅&#xff01; 文章目录 前言一、指令修饰符二、v-bind对于样式操作的增强三、v-model应用于表单元素 前言 在 Vue.js 中&#xff0c;指令是带有 v- 前缀的特殊属性&#xff0c;不同属性对应不同的功…

[原理理解] Swin Transformer相对位置编码理解

文章目录 简述相对位置编码的意义直观理解注意力相对位置获取必要性当前位置初步获取利用广播机制获取相对位置索引XY获取最后相对位置1获取最后相对位置2最终的相对位置值嵌入 简述 在看Swin Transformer的时候&#xff0c;一开始在相对位置编码这一块的理解上卡壳了挺久&…

27 Combobox组件

Tkinter ttk.Combobox 组件使用指南 ttk.Combobox 是 Tkinter 的一个高级控件&#xff0c;它结合了文本框和下拉列表的功能&#xff0c;允许用户从预定义的选项列表中选择一个值。ttk 模块是 Tkinter 的一个扩展&#xff0c;提供了更现代的控件外观和行为。以下是对 ttk.Combo…

hyperf json-rpc

安装 安装docker hyperf 安装 hyperf-rpc-server-v8 &#xff08;服务端&#xff09; docker run --name hyperf-rpc-server-v8 \ -v /www/docker/hyperf-rpc-server:/data/project \ -w /data/project \ -p 9508:9501 -it \ --privileged -u root \ --entrypoint /bin/sh \…

港口行业大数据BI建设方案(24页PPT)

方案简介&#xff1a; 港口行业BI建设方案旨在通过数据整合、分析、可视化及智能化决策支持等手段&#xff0c;提升港口运营效率与管理水平。它的建设实施有利推动港口数字化转型、是提升竞争力的关键举措。通过构建高效、智能的BI系统&#xff0c;港口企业能够实现对运营数据…

软设例题—哈夫曼树

哈夫曼树基本概念&#xff1a; 叶子结点的路径长度&#xff1a;结点到根的分支数量 树的路径长度&#xff1a;所有叶子结点路径长度之和 权&#xff1a;叶子结点的数值 叶子结点的带权路径长度&#xff1a;权重*路径 树的带权路径长度&#xff1a;所有叶子结点带权路径之和…

# Windows 系统安装 virtualbox/vmware 虚拟机教程

Windows 系统安装 virtualbox/vmware虚拟机教程 段子手-168 2024-8-28 一、virtualbox/vmware 简介 1、VirtualBox VirtualBox 是开源的、免费虚拟机软件。VirtualBox 是由德国 Innotek 公司开发&#xff0c;由 Sun Microsystems 公司出品的软件&#xff0c;号称是最强的免…

前端学习笔记-Web APIs篇-01

变量声明 变量声明有三个 var let 和 const 建议&#xff1a; const 优先&#xff0c;尽量使用const&#xff0c; 原因是&#xff1a; const 语义化更好很多变量我们声明的时候就知道他不会被更改了&#xff0c;那为什么不用 const呢&#xff1f;实际开发中也是&#xff0c…

如何使用ssm实现基于ssm的软考系统+vue

TOC ssm321基于ssm的软考系统vue 系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#x…

11 索引

目录 没有索引&#xff0c;可能会有什么问题认识磁盘 1. 没有索引&#xff0c;可能会有什么问题 所以&#xff1a;提高数据库的性能&#xff0c;索引是物美价廉的东西。不用加内存&#xff0c;不用改程序&#xff0c;不用调sql&#xff0c;只要执行正确的create index&#x…

Python 数据分析笔记— Numpy 基本操作

文章目录 学习内容&#xff1a;一、什么是数组、矩阵二、创建与访问数组三、矩阵基本操作 学习内容&#xff1a; 一、什么是数组、矩阵 数组&#xff08;Array&#xff09;&#xff1a;是有序的元素序列&#xff0c;可以是一维、二维、多维。 array1 [1,2,3] 或[a, b, c, d…

Littorine生物合成糖基转移酶和酰基转移酶-文献精读39

Functional genomics analysis reveals two novel genes required for littorine biosynthesis 功能基因组学分析揭示了两个Littorine生物合成所需的新基因&#xff0c;基因组挖掘很有效果~ 摘要 一些茄科药用植物能够生产药用莨菪烷类生物碱&#xff08;TAs&#xff09;&am…

MYSQL:简述对B树和B+树的认识

MySQL的索引使用B树结构。 1、B树 在说B树之前&#xff0c;先说说B树&#xff0c;B树是一个多路平衡查找树&#xff0c;相较于普通的二叉树&#xff0c;不会发生极度不平衡的状况&#xff0c;同时也是多路的。 B树的特点是&#xff1a;他会将数据也保存在非叶子节点。而这个…

样本存储需要注意的事项

在实验室和研究机构中&#xff0c;有一些样本是非常重要且需要特殊保护的&#xff0c;这些样本可能包括珍贵的细胞培养物、生物医学样本、药物试剂等等&#xff0c;为了保证这些样本的质量和完整性&#xff0c;采取一些特殊的措施来进行存储管理非常重要。 一旦这些珍贵样本出…

Undertow 性能、配置

一、性能对比 Tomcat vs Jetty vs Undertow性能对比,详细文章: Tomcat vs Jetty vs Undertow性能对比-腾讯云开发者社区-腾讯云 (tencent.com)https://cloud.tencent.com/developer/article/1699803压测指标的结果: 吞吐量:Undertow > Jetty > Tomcat响应时间&…

World of Warcraft [CLASSIC][80][Shushia] Call to Arms: Alterac Valley

Alterac Valley 奥特兰克山谷 明明能拿7000-9000荣誉&#xff0c;白送的大战场&#xff0c;废材太多&#xff0c;看不下去了&#xff0c;动不动就杀女人&#xff0c;丢墓地&#xff0c;最终拿什么3000荣誉&#xff0c;也不知道脑子装啥。 我们55级的时候就能把联盟打的不要不要…

物料类型 UNBW 和 NLAG

业务示例 公司的广告部门负责采购广告业务并承担相应的费用。这些宣传册不应该存储在广告部门&#xff1b;而应该存储在物料仓库中。并且需要基于数量而不是金额进行库存管理。因此这些物料的物料类型为未评估物料(UNBW)。 物料类型 UNBW 物料类型UNBW表示未评估物料。可以通…