栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

类与对象(一)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

类与对象(一)

目录

一、面向过程和面向对象

什么是面向过程?

什么是面向对象?

炒鸡蛋比方理解

面向过程

面向对象

二、类的概念

类到底是个啥,咋来的呢?

听我扯一下

引用

1.可以在其中定义函数

2.结构体名称可以做类型

 定义

注意

 举例

访问限定符

public

 private

 protected

封装

概念

c中问题

c++中解决

三、类的作用域

概念

四、类的实例化

概念

特征

五、计算类对象的大小

存储方式猜想

三种情况

类中既有成员变量,又有成员函数

类中仅有成员函数

类中什么都没有---空类

内存对齐

六、this指针

定义一个日期类

this指针解决上述疑惑

this指针特性

this例题

1.

 2.


一、面向过程和面向对象

什么是面向过程?

要完成一件事,关注的是过程,分析出求解问题的步骤,一步一步按照顺序完成,通过函数调用逐步解决问题。

什么是面向对象?

完成一件事,关注的是对象,将一件事情拆分成不同的对象,在对象中完成其该有的功能,靠对象之间的交互完成。

炒鸡蛋比方理解

面向过程

1.取出鸡蛋、2.敲开鸡蛋、3.将鸡蛋倒进碗里、4.筷子搅拌均匀、5.起锅、6.放油、7.点火、8.等待一定的时间后(时间不用太长,要不然把握不住),将鸡蛋倒入锅中、9.炸至金黄、10.闻到香味、11.出锅放到盘子里、12.撒点盐,开动。
 

按照上述过程,一步步实现,这就是面向过程。

面向对象

炒鸡蛋可分为中有哪些对象?

本人、食物(鸡蛋,盐,油)、餐具(碗、筷子、盘子,锅 )

将炒鸡蛋所需的东西,按照不同的性质分成不同的类,创建不同的对象,在对象中进行实现,最后通过对象的交互,完成炒鸡蛋。

通过各个对象间的相互交互:

本人和鸡蛋交互:完成打碎鸡蛋操作

本人和锅交互:完成起锅、出锅操作

……………

这样就可以实现各个功能,完成炒鸡蛋。

二、类的概念

类到底是个啥,咋来的呢?

听我扯一下

我们在炒鸡蛋中,食物餐具就是两个类,类包含了有相同共性的不同成员。

因此我们首先想到的是:C语言中的结构体! 

c++中出现了类,要实现各个功能,就必须做到类间的交互,功能的实现我们是用函数来实现的

因此得出结论:c++中出现的类,跟我们了解到的结构体和函数有关。

引用

在c++中,是支持C语言中的结构体的;

并且对结构体做了优化,升级成了类:

1.可以在其中定义函数

2.结构体名称可以做类型

例如:

在c中定义一个结构体

 在c++中定义结构体

 定义

 但是一般为了区分结构体和类,c++中,写类一般会将 struct 替换为 class

class className
{

    // 类体:由成员函数和成员变量组成

}; // 注意后面的分号

注意

1.成员变量名,前面或后面一般会有一些区别符号:

_ 或者字母等等,目的是为了区分

2.成员变量可以定义在成员函数下方,并且常定义在下方,因为类是一个整体,不会存在找不到的问题

类就是结构体升级来的类型,而对象类这个类型定义的变量。

升级的结构体类型 = 类

结构体变量 = 对象

 举例
#include 
using namespace std;

struct Food
{
	//成员函数
	void Init(const char* name, int num)
	{
		strcpy(_name, name);
		_num = num;
	}
	void Print()
	{
		cout << _name << " " << _num << endl;
	}

	//成员变量
	char _name[10];
	int _num;
};

int main()
{
	Food egg;
	egg.Init("鸡蛋",2);
	egg.Print();
	return 0;
}

可以将struct 替换为class

会发现出现访问问题!! 

 那就是访问权限的问题!!

class不加访问限定符,默认的访问权限时私有的

struct不加访问限定符,默认的访问权限是公有的

-->访问限定符

访问限定符

public

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

要解决上一步不可访问的问题:

加上 public:即可,如下:

 private

private 修饰的成员在类外不能直接被访问

若给结构体加上private:如下:

 protected

protected和private修饰的成员在类外不能直接被访问

当然是有区别的,现阶段我们只需要记住这两个效果相似就好。

封装

封装是c++面向对象的三大特性(封装、继承、多态)之一

概念

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

c中问题

数据的定义和操作数据的方法是分开的,就比如栈。定义栈的时候,数据是在栈的定义中,而初始化,进栈,栈顶元素这些方法是在定义外实现的。

这样的布局往往会造成操作的不规范,比如想要得到栈顶元素

规范操作就直接使用我们的函数就可以,但是有不规范的人可对数据进行直接访问,往往会产生误用,如下:

c++中解决

c++如何解决上述问题?

用到封装,可以强制规范操作。

将数据和操作数据的方法放在类中,并且用访问限定符进行修饰,防止对数据的直接操作。

一般情况下,类中,数据成员都是私有的,想要被访问的函数是公有的,不想被访问的是私有或者保护。

三、类的作用域 概念

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

和之前学到的命名空间一样,命名空间也是一个作用域。

在类中,一般存放的是数据和函数的声明,函数在类外定义。

也可以在类中定义,要注意:

在类中定义的函数默认是内联函数,因此简短的函数可以在类中直接定义。

那么类就应在头文件中:

函数实现单独放在一个.cpp中:

函数应在类域中,函数名前应指定作用域:

这样相当于函数包括函数下面的参数都是类中直接使用的,与访问限定符没有关系。

无论是哪一个限定符修饰的成员,在类中都可以被直接调用。

四、类的实例化 概念

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

特征

定义出一个类并没有分配实际的内存空间来存储它
一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
类相当于对象的模板

五、计算类对象的大小

类中既可以有成员变量,又可以有成员函数,如何计算一个类的大小?

存储方式猜想

对象中包含类的各个成员,函数和数据都占内存

 这里,我们创建两个对象,进行相同函数成员的调用:

说明了类创建的对象函数是共用的,数据不可能共用,因为每个对象的数据都是不同的。

若按照猜想来进行存储,类创建多个对象时,每个对象中都会保存一份代码,相同代码保存多次,浪费空间。

因此猜想错误

类的对象中只保存成员变量,成员函数存放在公共的代码段

那么类对象的大小计算就跟结构体差不多了,要注意内存对齐。

三种情况

类中既有成员变量,又有成员函数
class A1 {
public:
	void f1(){}
private:
	int _a;
};

只存储成员变量,按照计算结构体大小的方法,注意内存对齐

类中仅有成员函数
class A2 {
public:
	void f2() {}
};

对象中不存储成员函数,但是为了保证存在这个对象,会给对象开辟一个字节的空间

类中什么都没有---空类
class A3
{};

和仅有成员一样,不存储任何东西,为了说明类创建的对象存在,会相应的给予一个字节的空间

内存对齐

链接在这:自定义类型详解_i跑跑的博客-CSDN博客

六、this指针

定义一个日期类
//日期类
class Date
{
public:
	void Time(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;
	d1.Time(2001, 5, 15);
	d2.Time(2022, 10, 30);
	d1.Print();
	d2.Print();
	return 0;
}

this指针解决上述疑惑

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

编译器处理函数成员:

this指针特性

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

因为是const修饰,this指针不能更改

但是被this指针修饰的内容可以更改

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


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


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

 指针一般存放在栈中,有些编译器优化后会存放在寄存器中,更加方便高效。

this例题

1.
class A
{
public:
	void Show()
	{
		cout << "Show()" << endl;
	}
private:
	int _a;
};
int main()
{
	A* p = nullptr;
	p->Show();
}

 2.
class A
{
public:
	void Show()
	{
		cout << _a << endl;
	}
private:
	int _a;
};
int main()
{
	A* p = nullptr;
	p->Show();
}


类与对象的个人理解可能存在问题,有些牵强,有问题的地方希望伙伴们私信或在讨论区帮忙指正呀,学习笔记的记录,正确是前提,希望我们都能有所收获,共同进步!!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/886368.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号