C++ 类和对象(初篇)

2024-04-06 01:28
文章标签 c++ 对象 初篇

本文主要是介绍C++ 类和对象(初篇),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

类的引入

C语言中,结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。

而为了区分C和C++我们将结构体重新命名成class去定义

类的定义

标准格式:

class className
{// 类体:由成员函数和成员变量组成}; // 一定要注意后面的分号

注意:结构体不是函数,不管是C的struct还是C++的class 最后大括号完了都得加上“;”

class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号。 类中的元素称为类的成员:类中的数据称为类的属性或者成员变量; 类中的函数称为类的方法或者成员函数。

类的两种定义方式:

声明和定义都在结构体中:

同一个.cpp文件下#include <iostream>
using namespace std;
//. 声明和定义全部放在类体中
class Date
{
public://结构体中的函数void Init(int year,int month ,int day){_year = year;_month = month;_day = day;}void ShowDate(){cout << _year << "-" << _month << "-" << _day << endl;}
public://结构体中的变量int _year;//年int _month;int _day;};
int main()
{Date dt;dt.Init(2024, 4, 1);dt.ShowDate();return 0;
}

声明在.h,定义在.cpp(常用):

.h声明 person#include <iostream>
using namespace std;
//. 声明和定义全部放在类体中
class Date
{
public://结构体中的函数void Init(int year, int month, int day);void ShowDate();
public://结构体中的变量int _year;//年int _month;int _day;
};.C++ person#include "person.h"//结构体中的函数
void Date::Init(int year, int month, int day)
{_year = year;_month = month;_day = day;
}
void Date::ShowDate()
{cout << _year << "-" << _month << "-" << _day << endl;
}.C++ main
#include "person.h"int main()
{Date dt;dt.Init(2024, 4, 1);dt.ShowDate();return 0;
}

为什么使用域作用限定符?

回答:当在不同文件中声明定义,可能会出现相同函数,但是又因为结构体和命名空间等的包装,就需要专门::去打开。

成员变量前加“_”

成员变量(结构体里的变量)和函数参数变量都为相同的时,无法区分,为了更明显表现在代码上各变量关系,常用“_”来表示成员变量

类的访问限定符及封装:

上图一个会报错一个不会报错,其中最关键的在于public。由此我们能看出这个结构体默认是不让你胡乱在结构体外修改他的结构体内的变量的。

我们并不希望结构体内的有些东西会被修改,例如成员变量。

访问限定符:

说明:

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

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

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

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

封装:

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

面向对象的三大特性:封装、继承、多态

定义:封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互。

本质:通过将我们想要保护的隐私东西用保险箱保护(封装)起来。

通过不同的保护容器来实现不同的效果,例如,可以公开的信息就用透明箱子等;

类的作用域

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

类的实例化

定义:用类类型创建对象的过程,称为类的实例化(由图纸->实物)

1.类只是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际内存空间来存储它

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

简单理解:类只是给你设计了一个住宅区的建筑图纸,你可以用这份图纸在任何地方去建造住宅区,这个过程(给类申请空间)就叫做实例化过程;

//类--设计图纸
class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void ShowDate(){cout << _year << "-" << _month << "-" << _day << endl;}
public:int _year;int _month;int _day;
};int main()
{Date dt;//类的实例化--开实际空间dt.Init(2024, 4, 1);dt.ShowDate();return 0;
}

类的对象大小的计算

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

类的存储位置

注意:类里面函数运行的指令是存在代码段里,但是运行过程中的参数是存在栈里

结构体内存对齐规则:
1. 第一个成员在与结构体偏移量为0的地址处。

2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的对齐数为8

3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。

4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是 所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

类成员函数this指针

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

this指针的特性:

1.this指针的类型:类类型* const

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

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

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

this存在哪里?

1.栈,因为他是隐含形参

2.VS下,是通过ecx寄存器

空指针问题:

//测试空指针问题
class Date
{
public:void Init(int year, int month, int day){cout << this << endl;this->_year = year;this->_month = month;this->_day = day;}void Show(){cout << this << endl;cout << "func()" << endl;}
public:int _year;int _month;int _day;
};int main()
{Date d1;d1.Init(1111, 11, 1);Date* ptr = nullptr;ptr->Show();		   //正常运行(*ptr).Show();          //正常运行ptr->Init(3333, 33, 3);//运行崩溃return 0;
}

重点:解引用使用时主要看我们所申请的这个对象里包不包括我们要调用的函数或者变量。

解读代码:

结构体的解引用不一定都是有效的,例如ptr->Init()这里进去后要修改_year的数据,此时ptr解引用后并无实际存储数据空间,只是单纯的申请了了一个地址空间。所以此时解引用后是无法进行操作的。

show函数他只进行显示地址等并没有数据的操作过程

这篇关于C++ 类和对象(初篇)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/878657

相关文章

在java中如何将inputStream对象转换为File对象(不生成本地文件)

《在java中如何将inputStream对象转换为File对象(不生成本地文件)》:本文主要介绍在java中如何将inputStream对象转换为File对象(不生成本地文件),具有很好的参考价... 目录需求说明问题解决总结需求说明在后端中通过POI生成Excel文件流,将输出流(outputStre

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示

C++原地删除有序数组重复项的N种方法

《C++原地删除有序数组重复项的N种方法》给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度,不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(... 目录一、问题二、问题分析三、算法实现四、问题变体:最多保留两次五、分析和代码实现5.1、问题分析5.

C++ 各种map特点对比分析

《C++各种map特点对比分析》文章比较了C++中不同类型的map(如std::map,std::unordered_map,std::multimap,std::unordered_multima... 目录特点比较C++ 示例代码 ​​​​​​代码解释特点比较1. std::map底层实现:基于红黑

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

利用Python和C++解析gltf文件的示例详解

《利用Python和C++解析gltf文件的示例详解》gltf,全称是GLTransmissionFormat,是一种开放的3D文件格式,Python和C++是两个非常强大的工具,下面我们就来看看如何... 目录什么是gltf文件选择语言的原因安装必要的库解析gltf文件的步骤1. 读取gltf文件2. 提