C++面向对象:面向对象思想引入
1.从高处看面向对象
面向对象是一种编程思想,它并不是C++
特有的,所有编程语言(比如汇编,C
等)都可以实现面向对象。
面向对象语言就是设计语言特性时充分考虑并且原生支持面向对象特征的那些编程语言(例如Python
,Java
等),非面向对象语言没有原生支持面向对象,但是可以通过一些方法来实现面向对象(例如C
语言中struct
内部通过函数指针实现类似class
内部方法)。
面向对象之于编程,就好像比喻这种修辞法之于写作,写作的时候可以用比喻,也可以不用。面向对象只是编程语言语法层面的东西,不影响最终生成的二进制程序,也不关CPU
的事儿。
面向对象并不是一个单一概念,而是一揽子解决方案,里面有很多特性和细节。面向对象有三大特征:封装、继承、多态。
面向对象还会延伸出很多细节,不同编程语言会选择不同的应对方法,对于同一个问题可能C++
认为应该这样解决,而Java
认为应该那样解决。C++
的语法细节很多,因为C++
追求的是效率,要想效率高,语言细节就多。而Java
的语法细节少,优先考虑的是怎样使得程序简单,让程序员更不容易犯错,但它们都是面向对象的。
2.模拟单片机流水灯
- 2个LED分别是led1和led2,流水灯延时设置为1s。
2.1 用C语言常规方法实现
面向过程实现代码时,首先考虑完成一个任务需要经过几个步骤,然后将这些步骤按顺序一个个实现出来,类似于流水线一步一步的完成各个步骤。
对于实现2个灯的流水灯,有两种状态:灯1关、灯2亮以及灯1亮、灯2关,将这两种状态实现成led1_on_and_led2_off()
和led1_off_and_led2_on()
两个函数后,在加上延迟,按照我们想要的顺序放入循环就可以实现流水灯了。
模拟代码如下:
void main(void)
{
while(1)
{
led1_on_and_led2_off(); //1 on 2 off
sleep(1); //延时1s
led1_off_and_led2_on(); //1 off 2 on
sleep(1);
}
}
2.2 用C语言面向对象方法实现
用面向对象方法实现需要以下步骤:
- 第一步:面向对象编程的第1步是从理念上把要处理的任务当成一个对象,这里的对象就是LED灯。
- 第二步:将“任务完成”分解成“对象”的多个方法(
function
)的依次完成,现实中LED灯有一些功能,比如亮和灭,于是在用代码实现的时候,针对这些功能就可以认为一个LED对象应当具有这些方法。 - 第三步:抽象出你的“对象”的模型(类,
class
)来,尽管C
中没有class
,但是可以用struct
来表示,对象的功能方法用函数指针来实现,每个函数指针指向一个实际的函数,这些函数就是该类所具备的方法。 - 第四步:方法中需要用到的变量(
variable
)在面向对象的概念中定义为属性(property
),这里用struct
内包含的变量来实现。 - 第五步:实现“对象”抽象出的
struct
的全套数据结构和函数实体。 - 第六步:顺理成章的完成项目。
模拟代码如下:
1.首先定义对象,包含必要的属性(即变量)和方法(即函数):
typedef void (*pfunc_led_on_t)(void);
typedef void (*pfunc_led_off_t)(void);
typedef void (*pfunc_led_delay_t)(int);
void led_on(void);
void led_off(void);
void led_delay(int s);
struct led
{
//方法1:亮
pfunc_led_on_t von = led_on; //von是一个函数指针,是一个变量
//方法2:灭
pfunc_led_off_t voff= led_off; //voff是一个函数指针,是一个变量
//方法3:延时
pfunc_led_delay_t vdelay= led_off;
}
2.实例化对象,调用对象的方法来实现流水灯:
void main(void)
{
struct led led1,led2;//创建变量,本质就是实例化出一个对象
while(1)
{
led1.von();
led2.voff();
led1.vdelay(1)
led2.von();
led1.voff();
led2.vdelay(1)
}
}
- 可以看到,这里的代码并没有比前面的简单多少,但是这里重要的不是代码实现的难易,而是要体会面向过程与面向对象思维上的差异。
- 面向对象编程首先要想的是完成一个任务需要哪些对象,这些对象应该具有哪些方法。面向对象认为:万物皆是对象,所有操作全是对象的方法,所有变量全是对象的属性。
- 面向对象和面向过程是共存的,或者说面向对象是基于面向过程的而不是替代。
2.3 用C++面向对象方式实现
C++原生支持面向对象,通过class关键字:
class led
{
public:
void on(void);
void off(void);
}
void led::on(void)
{
}
void led::off(void)
{
}
- 上面的代码与第二部分中实现的功能是一样的,但是代码上明显简洁很多。
- 在
class
中类和内部的方法是天然绑定的,后续可以直接调用,而在前面的struct
中,绑定的是函数指针,函数指针和实际的方法并没有天然绑定,需要手工去赋值绑定。这就叫原生支持面向对象,因为用C++
实现面向对象非常方便,而C
需要绕很多弯子,但是实现出来的效果没有本质差别。
3.总结
面向对象是针对面向过程说的,编程时关注对象由过程转为对象。
面向对象的外部表象就是一种组织代码和写程序的方式。面向对象的本质是一种封装数据和看待问题的更高层次的视角,是应对越来越复杂问题,是处理越来越庞大程序的更有效的方法。语言由非面向对象升级到面向对象是自然而然的成长。