C++系列之三:面向对象概念透彻解析

发表时间: 2021-02-23 19:46

一:面向对象与面向过程

见下文

二:类的引入

学习C语言时,我们知道,结构体的作用是把一些具有不同类型的变量组合一起

struct Student{	char _name[20];	char _gender[3];	int _age;}123456

而在C++中,其结构体内不止可以定义变量,而且还可以定义函数

struct Student{	char _name[20];	char _gender[3];	int _age;		void SetStudentInfo(const char* name,const char* gender,int age)	{		strcpy(_name,name);		strcpy(_gender,gender);		_age=age;	}};int main(){	Student s;	s.SetStudentInfo("Bob","男",18);	return 0;}

这样定义后,结构体就可以被称为,只不过在C++中,我们更喜欢使用class代替struct

三:类的定义

(1)C++类的定义

根据以上叙述,所以在C++中,类是这样定义的

class className{	//成员函数	//成员变量	};//注意分号

所以简单来说,类就是属性和方法的集合,属性就是类中的数据,方法就是调用这些数据进行操作的函数

(2)类的两种定义方式

A:声明和定义全部放在类体中

要注意,成员函数如果在类中定义,编译器会将其当作内联函数处理。

class Person//人就是一个类{public://成员函数	void showinfo()//显示这个人的信息	{		std::cout<<_name<<std::endl;		std::cout<<_sex<<std::endl;		std::cout<<_age<<std::endl;	}public://成员变量	char* _name;	char* _sex;	int _age;

B:定义和声明分开放

这种方式最常采用

四:类的访问限定符及封装

(1)访问限定符

在前面类的定义中,有一个public,它属于访问限定符,除了public(公有)还有protected(保护)private(私有),他们用于修饰成员,比如public修饰的成员可以在类的外面直接被访问,而是用protectedprivate修饰的在类的外面不可以被直接访问


注意以下几点

  • 访问限定符的作用域是从该访问限定符出现的位置开始直到下一个访问限定符为止
  • class的默认访问权限(就是没有给出)为private,struct则为public
  • 访问限定符限制的是外面,就像锁子防的是外人

(2)封装

我们知道面向对象三大特性:封装,继承,多态

封装本质是一种管理手段,将属性(数据)和方法(接口)有机结合起来,再隐藏他们,只对外公开接口(函数)来和对象进行交互。不想给别人看的,使用protected/private进行修饰,而开放一些公有函数对成员进行合理访问。合理访问可以理解为阅读,不合理访问可以理解为改写(不准确)。

这里也就能说明,为什么C语言不支持大型项目的编写,因为它不支持面向对象,管理能力较弱,不是函数就是数据,就拿struct来说,其默认就是public的,安全性也堪忧,总的来说,用C语言编写项目,会感觉很乱,模块与模块独立性很差。

之前使用C语言实现过很多数据结构,比如说栈,我们都是新建一个工程然后分别建立它的声明,实现等文件,也就是说数据和方法是分离的,是自由的,如果换到C++中,按照面向对象考虑,一个栈就可以作为一个对象,这个对象有它的数据(动态增长的数组,长度,容量),还有它的方法(栈的初试线,压栈,出栈等等)。像这些数据,应该就是私有的,因为要防止外部操作改变数据,一旦数据出错,那么方法也就会受到相应的波及,然后这些操作按照实际需求让外部使用。

如:

//stack.hclass Stack//类{public:	void Init(int capacity=4);//缺省参数。声明private: //数据私有	int* _arr;	int _length;	int _capacity;//stack.cppvoid Stack::Init(int capacity)//该方法的实现{	_arr=(int*)malloc(sizeof(int)*capacity);	_length=0;	_capactiy=capacity;}

五:类的实例化

(1)类的实例化

类可以理解为一个房屋的图纸,这个图纸规定了一些基本信息,比如说这个房子朝向是什么,有几扇窗户,房子材料是什么等等。但是图纸终归就是图纸,纸上谈兵永远不会成为现实,要把这个图纸现实化,就要根据这个图纸的规定,修出相应的房子。当然,不按照图纸也能修,只不过修出来的房子可能成为四不像,或者不安全。这也就像C语言,没有图纸,接口随意写,数据任你改,是很自由,但是稍有不慎,房子就可能用不久了。

所以说根据图纸建造房子的过程,称为类的实例化,就像前面的栈一样,实例化出一个真正的栈,什么叫做真正的栈——这个栈它占用实际空间。一个图纸不可能只能造出一个房子,而是可以造出千千万万个房子,这个诸多房子本原都是一个,要想让他们之间有所区别,这取决于使用者,比如你和我都按照这个图纸了建造了相同的房子,但是我们对房子的装饰不同,所以看起来也就像两个不同的房子。回到栈,我们可以实例化出许许多多的栈,但是有些栈用于进行非递归操作,有些栈用于排序操作,他们就不是一样的了。

比如前面的栈可以实例化为

//stack.hclass Stack//类{public:	void Init(int capacity=4);//缺省参数。声明private: //数据私有	int* _arr;	int _length;	int _capacity;	//stack.cppvoid Stack::Init(int capacity)//该方法的实现{	_arr=(int*)malloc(sizeof(int)*capacity);	_length=0;	_capactiy=capacity;}//test.cppint main(){	Stack stack;	stack._arr=4;//操作非法,成员是private的	stack.Init();//初始化这个栈}

(2)面向对象

面向对象编程:其实很多学习编程的人,对于面向过程编程和面向对象编程这两个概念总是搞不清,具体的专业的定义在这里也不去说了,根据上面的叙述,我们可以这样去通俗的解释面向对象。

举个例子:我去洗澡,如果按照面向过程的角度考虑,那么我先进入浴室,然后打开水龙,然后洗漱,然后把身体擦干,也就是说面向过程关注的是解决问题的步骤;如果用面向对象考虑,只需记住一句话,万物皆对象,你是对象,水龙头也是对象,所以我先传递力的参数给浴室门,然后门就开了,然后我再传递消息给水龙头,水龙头得到消息,放水,最后传递消息给毛巾,毛巾利用它吸水的特性,调用吸水方法擦干身体,也就是说面向对象关注的是对象,将一个问题拆分为不同对象,依靠参数完成对象之间的交互

**为什么要进行面向对象编程?**这也是一个很值得思考的问题。举个例子,活字印刷术发明之前使用的是雕版印刷,这种方式弊端太大,如果需要改稿,那么雕版就必须重新雕刻,而活字印刷术则解决了这样的问题,需要改动,有可能只需改动几处。面向过程正如雕版印刷一样,也正如做数学题一样,中间某个环节一旦出现需求变更,那么整个工程几乎需要大改,要耗费大量时间精力。面向对象正如活字印刷术一样,如果需求变化了,可能只是修改其中一部分,也就是一个对象,而且最关键的一点是这些对象可以服用,进行活字印刷术一样,不是说这个对象在这个工程中发挥完之后,它就没有价值了,它还可能被其他工程所用。