在c语言中,我们将结构体作为一种自定义类型,结构体中可以存储一些内置类型的变量,例如int a,double b,char c,还可以存储一些结构体变量,例如struct student s1,struct data d1等等,但是,结构体中是不能定义函数的,这样的话,当我们需要对一个类型进行描述,就只能定义它有哪些属性,而不能定义它有哪些方法,需要定义方法就需要在结构体外部进行定义,那么在使用时就需要调用各种函数进行操作。
在上述的描述中,让我们有一种感觉,c语言中对某种类型进行描述的时候,总是需要使用结构体内部的变量和使用外部的函数,使用起来较为复杂,关注的点非常多(既要关注结构体变量,又要关注函数的使用)。实际上,c语言就是一种典型的面向过程的编程语言,而我们刚才所描述的使用场景和方法,就是一种面向过程的使用场景和方法。
而这种不方便的编程情况,归根结底是由于c语言的结构体中不能定义函数。
c++解决了这个问题,c++中定义,在结构体中可以定义函数,这样就可以将变量和函数都放到结构体中,便于后续的使用。
总结起来就是:C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如:之前在数据
结构初阶中,用C语言方式实现的栈,结构体中只能定义变量;现在以C++方式实现,会发现struct中也可以
定义函数。而在c++中,我们更喜欢使用class来定义结构体,而这个结构体我们更喜欢称之为类。
类有两种定义方式
1.将类的成员变量和成员函数都放在类体中,但是我们不推荐这样做,因为这样做成员函数会被编译器当做内联函数处理,同时,当我们多次定义类时,其中的成员函数也被多次调用,这样会造成多次定义的问题。
2.类的声明放在.h文件中,成员函数的实现放在.cpp中,并且这两个文件的名称一致。但是要注意一个问题,成员函数前要加类名::进行作用域操作符设置,这个作用域操作符就是在告诉编译器,这个函数是Data类中的成员函数,而非全局作用域中的函数。
//以下是在Data.h文件中进行Data类中成员函数的实现
void Data::SetData(int year,int month,int day)
{
_year = year;
_month = month;
_day = day;
}
当然,还有一个问题,为什么上述这个代码中的年月日前要加下划线?也就是说在定义class Data时,年月日变量前为什么要加_ ?
//如果不加下划线,year指的到底是什么?形参还是成员变量,这样就说不清楚了,当然,成员变量如何进行命名,还是要看公司的名称要求
void Data::SetData(int year,int month,int day)
{
year = year;
month = month;
day = day;
}
C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其
接口提供给外部的用户使用。
c++为了向下兼容c语言,因此class也可以使用struct,那么c++中的class和struct到底有什么区别呢?
请看这样一个例子
当我使用struct进行类定义时,创建一个对象后,使用.就可以看到类中所有的变量和函数,但是,当我使用class定义类时,使用点进行查看时,就看不到任何变量和函数了。
看到这里可以感觉到,这两个写法会使得成员在类外被访问时有区别。
实际上,当我们使用struct进行定义类时,类中的成员变量和成员函数都会被默认设为公有,这样在类外就可以被访问了,而使用class定义时,会被默认设置为私有,这样就无法在类外进行访问了。
而公有和私有说的就是访问限定符,访问限定符共有三种。
对于访问限定符,有几条说明
- public修饰的成员在类外可以直接被访问
- protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
- 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
- 如果后面没有访问限定符,作用域就到 } 即类结束。
- class的默认访问权限为private,struct为public(因为struct要兼容C)
我们知道,面向对象有三大特性,分别是封装、继承、多态。
而在类和对象阶段,主要研究封装。
那么什么是封装呢?
对于电脑这样一个复杂的设备,提供给用户的就只有开关机键、通过键盘输入,显示器,USB插孔等,让用户和计算机进行交互,完成日常事务。但实际上电脑真正工作的却是CPU、显卡、内存等一些硬件元件。
我们用穿衣服举例子,人穿衣服有两个作用,御寒(防止失温)和遮体(暴露出一些接口便于交互),那么封装也是这样的作用,可以让使用者看到一些接口,便于交互,同时防止内部被干扰。
使用标准的说法就是:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
在C++语言中实现封装,可以通过类将数据以及操作数据的方法进行有机结合,通过访问权限来隐藏对象内
部实现细节,控制哪些方法可以在类外部直接被使用。
实际上,我们定义的函数,其本身就是一个作用域,在函数体内部定义的变量就是在这个作用域内有效,而类也是一样的,在类内所有的成员都在这个作用域中
例如:
class Person
{
public:
void PrintPersonInfo();
private:
char _name[20];
char _gender[3];
int _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{
cout << _name << " "<< _gender << " " << _age << endl;
}
一个类实际上就是对一种实体的抽象,我们定义好一个类之后,需要进行类的实例化,创建出一个实体来,这样才能使用这个对象,而一个类可以创建出多个对象。
值得注意的是。类本身是没有能力去存储数据的,只有实例化出来的对象才能存储数据,就像一个房屋的设计图纸是不能住人的,而通过设计图纸建造出来的房屋才是可以住人的。
class Data
{
int _year;
int _month;
int _day;
void SetData(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
};
//实例化
Data d1;