c++的类和对象(上)

news2024/9/27 9:20:49

前言

Hello,小伙伴们,今天我们将开启一个新的章节,一起来探寻c++的奥秘。

好,废话不多说我们我们现在开始我们今天的学习!!

1.类的定义

1.1类的定义格式

  • c++为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类体中的函数称为类的方法或者是成员函数。
  • 为了区分成员变量,一般习惯上成员变量会加一个特殊的标识,如果成员变量前面或者是后面加——或者是m的开头,注意c++中这个是不强制的,只是一些惯例,在一些公司中会有具体的要求。
  • c++中struct也可以定义类,c++兼容c语法中的struct中的用法,同时也对struct中的用法进行了升级,明显的变化是struct中也可以定义函数。一般情况下我们还是更推荐使用class定义类。
  • 定义在类中的成员变量函数,默认情况下都是加上inline的。

我们在这里先定义一个类来演示其效果:

class Date
{ 
public:
    void Init(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
private:
    // 为了区分成员变量,⼀般习惯上成员变量
    // 会加⼀个特殊标识,如_ 或者 m开头
    int _year; // year_ m_year
    int _month;
    int _day;
};
    int main()
    {
        Date d;
        d.Init(2024, 3, 31);
        return 0;
    }
}

通过的上面的代码,我们可以直观的看到c原因与c++的区别,定义类的操作上使得c++拥有了更加强大功能,使代码也变得更加的简洁。

我们还可以在Date类中定义另一个函数来实现数据的打印,使得功能更加的全面:

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:
    // 为了区分成员变量,⼀般习惯上成员变量
    // 会加⼀个特殊标识,如_ 或者 m开头
    int _year; // year_ m_year
    int _month;
    int _day;
};
    int main()
    {
        Date d;
        d.Init(2024, 3, 31);
        d.Print;
        return 0;
    }

 1.2访问限定符

  1. c++一种实现封装的方式,用类将对象的属性与方法结合在一起,让对象的属性与方法结合在一起,让对象更加的完善,通过访问权限选择性的将其接口提供给外部的用户使用。
  2. public修饰的成员变量在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访问,protected和private是一样的,到后面的继承章节会着重介绍他们。
  3. 访问权限的作用域从该访问限定符出现的位置开始直到下一个限定符出现,如果后面没有再出现限定访问符号,作用域到}即类截止。
  4. class定义成员的时候没有被限定修饰符修饰时默认设置为private,struct默认设置为public。
  5. 一般成员变量都会被限制为private或者是protected,需要给别人使用时的成员函数会被修饰为public。

 

1.3类域

类定义了一个新的作用域,类的所有成员都在类的作用域中,在类体外定义成员时,需要使用::作用域操作符指明该函数出自那个类域。

类域影响的是编译的查找规则,下面程序Init如果不指定类域Stack,那么编译器就把Init当成全局函数,那么编译时,如果找不到array等成员的声明/定义在哪里,就会出现报错。指定类域·Stack,就是知道Init成员函数,当前域找不到array等成员,就会到类域中去寻找。

 

#include<iostream>
using namespace std;
class Stack
{ 
    public:
        // 成员函数
        void Init(int n = 4);
    private:
        // 成员变量
        int* array;
        size_t capacity;
        size_t top;
};
// 声明和定义分离,需要指定类域
void Stack::Init(int n)
{
    array = (int*)malloc(sizeof(int) * n);
    if (nullptr == array)
    {
    perror("malloc申请空间失败");
    return;
} 
capacity = n;
top = 0;
}
int main()
{
    Stack st;
    st.Init();
    return 0;
}

2.实例化

2.1实例化概念

  • 用类类型在物理的内存中创建对象的过程,称之为类实例化出对象。
  • 类时对象进行一种抽象描述,是一个模型一样的东西,限定了类有哪些成员变量,这些成员都是声明没有开辟空间,用类实例化处对象时,才会开辟空间。
  • 一个类可以实例化出多少个对象,实例化出的对象占用物理空间,存储类成员变量。打个比方:类实例化出对象就像现实中使用建造图建造房子,类就是设计图,设计图规划了有多少个房间,房间的大小和功能等,但并没有实体的材料建造成型,不能使用,用设计图建造出房子才能住人。同样,类就是像设计图一样的东西,不能存储数据,实例化出的对象则可以分配物理内存来存储数据。

#include<iostream>
using namespace std;
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 main()
{
// Date类实例化出对象d1和d2
Date d1;
Date d2;
d1.Init(2024, 3, 31);
d1.Print();
d2.Init(2024, 7, 5);
d2.Print();
return 0;
}

 2.2对象的大小

分析一下类对象中的那些成员呢?类实例化的每一个对象,都拥有独立的空间,,所以对象中肯定包含成员变量,那么成员函数是否包含其中呢?

首先函数被编译后只是一段指令,对象没有办法在存储,这些指令存储在一个特定的区域(代码段),那么对象中非要存储的话,只能是成员函数的指针.在分析一下,对象中是否有存储指针的必要,Date实例化d1,d2两个对象,d1\d2都有自己独立的成员变量_year/_month/_day储存在各自的数据,互不干扰,但是d1和d2的的成员函数的指针确实一样的,存储在类中就有点浪费空间了。

接下来对象的大小计算还是会涉及我们之前在结构体学到的内存对齐,这里我们就不再赘述,还不是很清楚的同学可以再去看看我之前写的这篇文章: http://t.csdnimg.cn/oNC9Y

 这里我们演示一个特殊的按例:

/ 计算⼀下A/B/C实例化的对象是多⼤?
class A
{ 
public:
void Print()
{
cout << _ch << endl;
}
private:
char _ch;
int _i;
};
class B
{ 
public:
void Print()
{
//...
}
};
class C
{};
int main()
{
A a;
B b;
C c;
cout << sizeof(a) << endl;
cout << sizeof(b) << endl;
cout << sizeof(c) << endl;
return 0;
}

运行一下,我们来看看会得到怎样的结果:

 上面的程序我们可以看到运行的结果是,B和C的类对象大小是1,为什么没有对象成员但还是会占用存储空间呢?

因为如果一个字节都不给,怎么来表示对象存在过呢?所以这里给了一个字节,存粹就是为了站位标识对象的存在。

3.this指针

  • Date类中有Init函数和Print函数,函数体中没有关于不同对象的区分,那当d1调用Init和Print函数时,该函数是如何知道该访问的是d1的对象还是d2的对象呢?这里就要看c++给的一个隐含的this指针解决了这里的问题。
  • 编译器编译后,类的成员函数默认都会在形参的第一个位置,增加一个当前类类型的指针,叫做this指针。
  • 类中的成员函数访问成员变量是,本质都是通过this指针访问的,入Init函数中给_year赋值,this->_year = year.
  • c++规定不能在实参和形参的位置显示this指针(编译时编译器会进行处理),但是在函数体内可以将this指针显示使用。 
#include<iostream>
using namespace std;
class Date
{ 
public:
// void Init(Date* const this, int year, int month, int day)
void Init(int year, int month, int day)
{
// 编译报错:error C2106: “=”: 左操作数必须为左值
// this = nullptr;
// this->_year = year;
_year = year;
this->_month = month;
this->_day = day;
} 
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
// 这⾥只是声明,没有开空间
int _year;
int _month;
int _day;
};
int main()
{
// Date类实例化出对象d1和d2
Date d1;
Date d2;
// d1.Init(&d1, 2024, 3, 31);
d1.Init(2024, 3, 31);
d1.Print();
d2.Init(2024, 7, 5);
d2.Print();
return 0;
}

好,今天的学习就到这里,咱们下期再见,拜拜!!! 

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

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

相关文章

【Python】requests的response.text 和 urllib.request 的 response.read()的区别

刚写代码的时候&#xff0c;我经常会把requests 和 urllib下的request 包搞混&#xff0c;这两个请求响应的方法看起来很相似&#xff0c;但是写获取的方法是不一样的。 前者requests 是用response.text 来获取源码&#xff0c;而 urllib.request是用 response.read() 来获取h…

Visual Studio Code搭建VUE开发环境

Vue.js 是一款易学易用&#xff0c;性能出色&#xff0c;适用场景丰富的 Web 前端框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;提供容易上手的 API 和一流的文档。可以用来开启PC网页、移动端网页页面、小程序等等 实验环境 VS Code 1.88.1Node 20.16.0Vue3.2…

社交及时通讯平台完整版源码,uniapp技术,可打包成app

源码简介&#xff1a; 全原生&#xff0c;从底层开始结构就完全不一样&#xff0c;mongodb的库&#xff0c;uniapp混编手端&#xff0c;二开难度要比视酷或者酷信容易很多。全开源&#xff0c;带开发文档。前端用的是uniapp技术&#xff0c;所以是多端合一&#xff0c;可以做h…

vue中openlayers过滤高亮显示某个图层

vue中openlayers过滤高亮显示某个图层 openlayers库没有直接支持这样设置&#xff0c;所以可以使用库&#xff1a;ol-ext&#xff0c;地址&#xff1a;https://viglino.github.io/ol-ext/examples/filter/map.filter.crop.html 效果&#xff1a; 关键代码&#xff1a; /**…

PCI多路复用开关模块、PCI总线开关卡—PCI2612

简介&#xff1a; 阿尔泰科技 PCI2612是一款独立性的中密度 PCI多路复用开关模块&#xff0c;该模块采用机电继电器&#xff0c;为承载大功率信号提供了出色的性能&#xff0c;同时具有低热偏移&#xff0c;可在低电压电平下进行精确测量。PCI2612还具有监测继电器的板载继电器…

Linux 调试器 —— gdb 的使用

Linux 调试器 —— gdb 的使用 前置条件debug 模式 和 release 模式gdb 下载 基础操作退出调试器查看源代码运行程序断点打断点查看断点取消断点关闭断点开启断点 单步执行逐过程逐语句 打印表达式值、变量值、地址等等单次查看常显示 运行至下一个断点处运行完所在函数&#x…

前端web开发HTML+CSS3+移动web(0基础,超详细)——第4天

一&#xff0c;-div和span标签和字体实体 1.无语义的布局标签 作用&#xff1a;布局网页&#xff08;划分网页区域&#xff0c;摆放内容&#xff09; div:独占一行 span:不换行 <div>div标签&#xff0c;独占一行</div> <span>span 标签&#xff0c;不换行…

Transformer(二)

一、TNT模型 VIT只针对patch进行建模&#xff0c;忽略了其中更小的细节 TNT基本计算 内部transformer重组成新的向量新向量再通过全连接改变输出的特征大小内部组合后的向量与patch编码大小相同最后与原始输入patch向量相加 二、SwinTransformer 解决了哪些问题&#xff1a…

英特尔凌动® P5300 和 P5700 处理器使企业能够优化现代网络基础架构、安全加速器和存储设备之间的性能和成本平衡。

介绍英特尔凌动 P5300 和 P5700 处理器 英特尔凌动处理器提供核心数和硬件功能各异的多种配置&#xff0c;用于支持不同的边缘用例。基于 10 纳米工艺的先进微架构与一组强大的加速器相结合&#xff0c;带来卓越的每核性能和先进的数据包处理能力。这些平台基于高能效的系统级…

SQL Server 的透明数据加密

透明数据加密是SQL Server数据库安全众多特性中的一个&#xff0c;本文只针对透明数据加密。 在此测试之前&#xff0c;已经按照文档如何快速获得一个测试用SQL Server企业版创建了一个SQL Server 2019&#xff0c;并按照文档为SQL Server安装示例数据库AdventureWorks安装了…

Aspose.Words.dll 插入模板表格,使用的是邮件合并MailMerge功能,数据源是DataTable或list对象,实例

本实例中的实例功能有: 1、 Aspose.Words.dll 插入模板指定域替换为文字或html标签,见1 2、Aspose.Words.dll 插入模板表格,使用的是邮件合并MailMerge功能,数据源是DataTable或List对象(将list转换成DataTable),见1和2 3、word转换Pdf文件,见1 4、将多个word输出文…

PXE实现批量主机开机自动安装

华子目录 前言PXE装机的基本工作原理PXE组件实验前的准备工作1.VM进入虚拟网络编辑器关闭dhcp功能2.从RHEL7母机上克隆一个server端和client端3.配置server端4.关闭firewalld和selinux5.mobaxterm使用ssh -X连接到server端6.anaconda-ks.cfg介绍6.1文件概述6.2文件内容6.3文件使…

dbeaver 导入sql 报错,ERROR 2059 (HY000)

dbeaver 导入sql 报错。 C:\Users\admin\AppData\Roaming\DBeaverData\drivers\clients\mysql\win\mysql.exe --default-character-setutf8mb4 -u root --host222.85.214.245 --port11076 res_protect Task ‘MySQL script’ started at Wed Aug 07 16:31:58 CST 2024 ERROR 2…

【c++】基础知识——快速入门c++

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;C 目录 前言 一、手搓一个Hello World 二、命名空间namespace 1.命名空间的定义 2.命名空间的使用 3.命名空间补充知识 三、c中的输入和输出 四、缺省参…

哈哈哈日记

最近真的没有什么灵感更新&#xff0c;大家都在更啥呀!我就像天气一样时好时坏的&#xff0c;嘴上每天都是“好想死”&#xff0c;但是身体稍微有点不舒服立马就去看医生&#xff0c;委屈了啥都不能委屈自己&#xff0c;2块钱的矿泉水舍不得买&#xff0c;35一杯的咖啡我倒是看…

Pygame制作简单的跑酷游戏

今天我们来看看如何使用Pygame框架制作一个简单的跑酷游戏。这个游戏包含了基本的游戏元素,如玩家角色、障碍物、背景、音效等,可以作为入门Pygame游戏开发的一个不错的示例。 游戏概述 这是一个简单的横版跑酷游戏,玩家控制一个忍者角色,通过跳跃来躲避迎面而来的各种障碍物…

C++设计模式(代理模式)

1. 电话虫 在海贼中&#xff0c;有一种神奇的通信工具叫做电话虫&#xff08;Den Den Mushi&#xff09;&#xff0c;外形如蜗牛&#xff0c;身上带有斑点或条纹或通体纯色&#xff0c;壳顶上有对讲机或按键&#xff0c;不接通时会睡觉&#xff0c;接通时会惊醒&#xff0c;并发…

bpmn简单使用(制作流程图)

1、先下载依赖&#xff0c;下面是我下载的版本 "bpmn-io/properties-panel": "^3.23.0", "bpmn-js": "^17.9.1", "bpmn-js-properties-panel": "^5.6.1", "camunda-bpmn-moddle": "^7.0.1",…

【鸿蒙开发基础学习】HSP-应用程序包开发与使用

HSP - 应用程序包开发与使用 HSP HSP&#xff08;Harmony Shared Package&#xff09;是动态共享包&#xff0c;可以包含代码、C库、资源和配置文件&#xff0c;通过HSP可以实现代码和资源的共享。HSP不支持独立发布&#xff0c;而是跟随其宿主应用的APP包一起发布&#xff0…

【开端】web系统中返回状态码组织管理

一、绪论 http web系统接口返回状态码有很多中&#xff0c;包括行业内定的状态码 &#xff0c;比如200 表示成功&#xff0c;500表示服务器系统不可用&#xff0c;但是有包含很多业务上自定义的状态码。比如阿里&#xff0c;腾讯这些公司的产品会定义很多自己公司产品的状态码…