本文通过面向对象的概念以及通俗易懂的例子介绍面向对象引出类和对象。最后通过与之有相似之处的C语言中的struct一步步引出C++中的类的定义方式,并提出了一些注意事项,最后描述了类的大小的计算方法。
一、什么是面向对象?
1.面向对象的概念
面向对象(Object-Oriented Programming,简称OOP)是一种编程范式,它通过将数据和操作数据的方法封装在对象(Object)中,以提高代码的重用性和可维护性。面向对象编程的核心概念包括:
- 对象(Object):对象是类的实例,包含数据和方法。数据通常被称为属性或字段,方法则是能够操作这些数据的函数。
- 类(Class):类是对象的蓝图或模板,定义了对象的属性和方法。通过类可以创建多个对象。
- 封装(Encapsulation):将数据和操作数据的方法封装在对象中,并对外界隐藏对象的内部实现细节。通过提供公开的方法(接口)来操作对象的数据。
- 继承(Inheritance):一个类可以继承另一个类的属性和方法,从而实现代码重用。继承使得子类可以扩展父类的功能。
- 多态(Polymorphism):多态允许不同类的对象可以通过相同的接口调用,具体调用的 实现根据对象类型的不同而不同。这使得程序具有更好的灵活性和可扩展性。
2.面向对象的简单例子
█ 类(Class)
可以想象成一个蓝图或模板。例如,我们要创建一辆车,那么“车”就是一个类。这个类包含了所有车共有的属性,比如颜色、品牌、型号等,还有车能做的事情,比如启动、加速、刹车等。
█ 对象(Object)
是根据类创建的具体实例。比如,根据“车”这个类,我们可以创建具体的车:一辆红色的特斯拉,一辆蓝色的宝马等。每辆车都是一个对象,它们都有各自的颜色、品牌等属性,但它们都是从“车”这个类创建出来的。
█ 封装(Encapsulation)
把车的属性(比如颜色、品牌)和行为(比如启动、加速)封装在一起,就像把这些东西装在一个盒子里。外面的人只能通过车提供的功能(比如按下启动按钮)来与车互动,而不需要知道车内部是怎么工作的。█ 继承(Inheritance)
如果我们有一个“电动汽车”类,它可以继承“车”类的所有属性和行为,并且添加一些自己的特性,比如电池容量。这就像是你有了一个标准车的模板,然后在这个基础上进行扩展,增加一些新的功能。█ 多态(Polymorphism)
多态让不同类型的车在调用相同的“启动”方法时表现不同。比如,对于一辆传统汽车,启动可能是点火;而对于电动汽车,启动可能是激活电池。尽管调用的都是同一个“启动”方法,但具体的行为是根据车的类型来决定的。
3.面向对象VS面向过程
面向过程(Procedural Programming)是一种编程范式,它主要通过过程(函数或方法)的调用来解决问题,程序的执行是按照一系列步骤顺序进行的。
C语言是面向过程的语言,而C++是面向对象的语言。
如果我们要用程序思维解析洗衣服这一行为。面对过程的编程需要倒入水、导入洗衣粉、清洗衣物、拧干...等一系列的函数,然后使用者一一调用这些函数,而面向对象就像一个洗衣机,他将洗衣服的这些方法和对象糅合在一个类里,使用者只要拿一些衣物放入洗衣机就可以直接完成这一行为。
二、类的简单使用
1.结构体与类
结构体和类是没有什么直接的关系的,但是他们还是有一些相似之处。
在C语言中,结构体可以将不同类型的数据结合在一起,可以描述数据成员的属性但是不能有方法(函数)存在,否则就会报错。
![](https://i-blog.csdnimg.cn/direct/96443dc5325043b4a6967a1d7864b847.png)
而C++是兼容C语言的,C++中仍然有结构体这个概念,C语言文件中能够运行的它都可以执行,但是C++中的结构体有一些扩展,使得其与类非常的相似。
![](https://i-blog.csdnimg.cn/direct/9e5ebd383fae4dd7827d886862acf972.png)
2.结构体——>类
1)struct——>class
想要从结构体转变为类,首先需要将前面的修饰struct改为class
2)访问限定符
①定义
在C++中,访问限定符(Acess Specifiers)用于控制类或者结构体成员的访问权限。一共有三个,分别为public(公开访问,任何地方都可以访问) 、protected(保护访问,只有类本身、友元和派生类可以访问)、plivate(私有访问,只有类本身和友元可以访问,派生类无法访问)。
(成员声明为public后,这些成员可以从类的外部直接访问,这通常用于类的接口部分。)
②使用
class date
{
public:
void print_d()
{
cout << year << "年" << month << "月" << day << "日" << endl;;
}
private:
int _year;
int _month;
int _day;
};
③注意事项☆
- 类定义的惯例:成员变量一般都设为私有(而且内部的变量一般都会在前面稍加修饰,如_year)
- 访问权限作用域从该访问限定符出现的位置直至下一访问限定符出现或到类体结束为止
- class的默认访问权限为private,struct为public
- 访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别。(访问限定符只是在编译期间进行访问控制,防止在代码中不正确或不安全的访问,但是这些数据在内存上是没有什么差别的)
3.类的定义
class ClsssName
{
//类体:成员函数和成员变量
public:
//...成员函数之类的
private:
//...成员变量
}; //;不能忘
- 类里定义的函数最好是定义和声明分离,在定义处要指明类域
- (void class::print_d() {//...} )。默认在类里面定义的是inline(会进行隐式内联)。
4.类的实例化(对象)
类是一个蓝图,对象就是蓝图的实现,类与对象是一对多的关系。
1.对象的定义
基于以上的Date类进行实例化:(分别创造了d1,d2和a三个对象)
int main()
{
Date d1;
Date d2;
Date a;
return 0;
}
此时d1._year++;和d2._year++;是不一样的,它们是两个对象。
2.类对象的大小
一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量。类并没有占实际的物理空间,是不能直接使用的,但是我们可以描述类的大小,它和对象的大小是一样的。
- 一个类的大小,实际就是在内存对其的条件下该类中成员变量的大小,因为不同的对象每次调用的函数是一样的,为了避免每次实例化都创建一个新函数,类的成员函数被保存在公共代码段,不算在类的大小中。
- 一个空类或者只有成员函数的类大小是一个字节。虽然里面没有成员变量,编译器给空类一个字节来唯一标识这个类的对象。
以下是在vs编译器下的大小计算(vs默认对齐数为8)
class date
{
private:
int year;
int month;
int day;
public:
void print_d()
{
cout << year << "年" << month << "月" << day << "日" << endl;;
}
};
//sizeof(date)为12
class A
{
int _a;
int* _b;
short _c;
float _d;
};
//int4,int*8,short2,float4 sizeof(A)为24
class B
{
void func();
};
//sizeof(B)为1
class D
{
class E{};
};
//sizeof(D)为1
-The End-