Bootstrap

c++:面向对象编程

从高处看面向对象

  • 从高处看面向对象
    2.1.1.1、面向对象是一种编程思想
    (1)面向对象并不是C++特有的,所有编程语言都可以面向对象
    (2)面向对象语言就是设计语言特性时充分考虑并且原生支持面向对象特征的那些编程语言
    (3)面向对象之于编程,就好像比喻修辞法之于写作
    (4)面向对象只是编程语言语法层面的东西,不影响最终生成的二进制程序,也不关CPU的事儿
    (5)深度装x:面向对象是一种哲学

  • 面向对象并不是一个单一概念
    (1)面向对象三大特征:封装、继承、多态
    (2)面向对象还会延伸出很多细节,而不同编程语言会选择不同的应对方法
    (3)C++的语法细节很多,而Java的语法细节少,但都是面向对象的
    (4)面向对象是设计模式的基础,凡事从简单到复杂其实学起来顺理成章

  • 如何学习面向对象
    (1)高屋建瓴,先理解理论和需求,再关注语法细节
    (2)要先有一定框架思想,先有一定(写或者至少是读)代码量积累
    (3)要从已知到未知,从案例中去领会,才能有真正的感受,才能真正学会

  • 本课程如何讲面向对象
    (1)先提出一个简单问题,譬如单片机或嵌入式编程中最简单的流水灯问题。
    (2)第一步:用C语言常规方法实现,理解
    (3)第二步:用C语言面向对象方法实现,边分析边讲解边实现,再理解
    (3)第三步:用C++面向对象方式实现,对比第二步,再理解
    (4)第四步:逐一详解面向对象的各特征,并且用C++来实例讲解实现
    (5)第五步(未来自己做):碰到其他语言如Java等,用本课程讲的思路结合具体语言语法往进套即可

纯C语言传统方式实现流水灯

  • 问题描述和分析
    (1)假设有2个LED,分别是led1和led2
    (2)流水灯延时设置为1s

  • 用C语言实现
    (1)用printf打印信息表示LED亮灭
    (2)用sleep来延时
    (3)编写各个LED亮灭的函数
    (4)循环形成流水灯效果

//方法一
int initled1on2off() { cout << "led1on2off" << endl; }
int initled1off2on() { cout << "led1off2on" << endl; }

int test0625001() {

  while (1) {
    initled1on2off();
    usleep(1000 * 1000);
    initled1off2on();
    usleep(1000 * 1000);
  }

  return 0;
}

升级版纯C实现流水灯

  • 使用函数传参简化
    (1)设计2个参数,分别是led编码和亮灭编码
    2.1.3.2、封装参数为结构体
    (1)设计1个结构体类型,包含2个参数
    (2)用结构体变量来实现传参

  • 对比分析
    (1)升级版和原始版效果完全一样
    (2)升级版对代码量有简化
    (3)升级版对编程难度和组织结构性有改善
    (4)升级版具备极强的扩展性
    (5)问题越复杂,升级版的优势会越显现出来

typedef struct Led_ {
  int index;
  int status;
} Led;

int setledsta(Led led) {
  for (int i = 1; i < 4; i++) {
    if (led.index == i && led.status == 1) {
      cout << "led" << i << "on" << endl;
    } else {
      cout << "led" << i << "off" << endl;
    }
  }
}
int test0625002() {
  Led led;
  while (1) {
    led.index = 1;
    led.status = 1;
    setledsta(led);
    usleep(1000 * 1000);
    led.index = 2;
    led.status = 1;
    setledsta(led);
    usleep(1000 * 1000);
    led.index = 3;
    led.status = 1;
    setledsta(led);
    usleep(1000 * 1000);
  }

  return 0;
}

面向对象方式纯C实现流水灯

  • 分析
    (1)面向对象编程的第1步,是从理念上把你要处理的任务当成一个对象
    (2)第2步,将你的“任务完成”分解成“对象”的多个方法(function)的依次完成
    (3)第3步,抽象出你的“对象”的模型(类,class)来,用struct来表示,对象的功能方法用函数指针
    (4)第4步,方法中需要用到的变量(variable)定义为属性(property),用struct内包含的变量来实现
    (5)第5步,实现你的“对象”抽象出的struct的全套数据结构和函数实体
    (5)第6步,顺理成章的完成项目

  • 分析和实战
    (1)分析出本案的对象“led”
    (2)分析出对象的方法:led.on, led.off, led.delay
    (3)抽象出对象的模型:struct led{};

  • 编程实现
    (1)实现struct led的全部数据结构和方法
    (2)用面向对象的思路实现整个程序

  • 拓展要求和实现1
    (1)拓展要求:要求将延时从1s延长到2s
    (2)分析回顾传统的做法
    (3)分析并实现面向对象的做法:增加一个属性sDelay

  • 拓展要求2
    (1)拓展要求:将整个N颗LED视为一个对象来实现
    (2)分析

  • 总结
    (1)本案实现并不难,有一定C功底的可以很容易看懂,关键是体会这种思路
    (2)函数指针只是手段,并不是关键点
    (3)面向对象认为:万物皆是对象,所有操作全是对象的方法,所有变量全是对象的属性。
    (4)面向对象和面向过程是共存的,或者说面向对象是基于面向过程的,而不是替代。



typedef int (*p1)(int, int);
typedef int (*p2)();
typedef struct Led2_ {
  //属性
  int index;
  int status;
  //方法
  int (*p1)(int, int);
  int (*p2)();
} Led2;

int ledop(int index, int sta) {
  if (sta == 1) {
    cout << "led" << index << "on" << endl;
  } else {
    cout << "led" << index << "off" << endl;
  }
  return 0;
}
int leddelay() {
  usleep(1000 * 1000);
  return 0;
}

int test0625004() {
  Led2 led1;//实例化
  led1.p1 = ledop;//初始化
  led1.p2 = leddelay;

  Led2 led2;
  led2.p1 = ledop;
  led2.p2 = leddelay;

  Led2 led3;
  led3.p1 = ledop;
  led3.p2 = leddelay;
  while (1) {
    //步骤1:led1-on
    led1.index = 1;
    led1.status = 1;
    led1.p1(led1.index, led1.status);//执行
    led1.p2();

    led2.index = 2;
    led2.status = 0;
    led2.p1(led2.index, led2.status);
    led2.p2();

    led3.index = 3;
    led3.status = 0;
    led3.p1(led3.index, led3.status);
    led3.p2();

    //步骤2:led2-on
    led1.index = 1;
    led1.status = 0;
    led1.p1(led1.index, led1.status);
    led1.p2();

    led2.index = 2;
    led2.status = 1;
    led2.p1(led2.index, led2.status);
    led2.p2();

    led3.index = 3;
    led3.status = 0;
    led3.p1(led3.index, led3.status);
    led3.p2();

    //步骤3:led3-on
    led1.index = 1;
    led1.status = 0;
    led1.p1(led1.index, led1.status);
    led1.p2();

    led2.index = 2;
    led2.status = 0;
    led2.p1(led2.index, led2.status);
    led2.p2();

    led3.index = 3;
    led3.status = 1;
    led3.p1(led3.index, led3.status);
    led3.p2();
  }
  return 0;
}

多个LED看做一个整体对象:

typedef struct Led1_ {
  int index;
  int status;
  int (*p)(int, int);
  int (*p2)();
} Led1;

int led1(int dex, int sta) {
  for (int i = 1; i < 4; i++) {
    if (dex == i && sta == 1) {
      cout << "led" << i << "on" << endl;
    } else {
      cout << "led" << i << "off" << endl;
    }
  }
}
int leddelay1() {
  usleep(1000 * 1000);
  return 0;
}
int test0625003() {
  Led1 led;
  led.p = led1;
  led.p2 = leddelay1;
  while (1) {
    led.index = 1;
    led.status = 1;
    led.p(led.index, led.status);
    led.p2();

    led.index = 2;
    led.status = 1;
    led.p(led.index, led.status);
    led.p2();

    led.index = 3;
    led.status = 1;
    led.p(led.index, led.status);
    led.p2();
  }
  return 0;
}

用C++实现流水灯

  • C++中用struct实现
    升级用class实现
    体会C++比C的差异
    (1)C++源生支持面向对象的语法特性,所以实现起来舒服一些
    (2)目前为止其实感受不到C++比C太大的优势和差别,因为还没用到更多更复杂的特性。
    (3)C++最早叫C with class,可以认为C++就是在C的基础上增加了很多面向对象的实现特性
typedef struct Testled_ {
public:
  //属性
  int num;
  //方法
  void on(void);
  void off(void);
} Testled;
void Testled_::on(void) { cout << "on" << endl; }
void Testled_::off(void) { cout << "off" << endl; }
int test0625005() {
  Testled led1, led2, led3;
  while (1) {
    //步骤1
    led1.on();
    led2.off();
    led3.off();
    usleep(1000 * 1000);
    //步骤2
    led1.off();
    led2.on();
    led3.off();
    usleep(1000 * 1000);
    //步骤3
    led1.off();
    led2.off();
    led3.on();
    usleep(1000 * 1000);
  }
  return 0;
}

升级一下:

typedef struct Testled_ {
public:
  //属性
  int index;
  //方法
  void on(void);
  void off(void);
} Testled;
void Testled_::on(void) { cout << "led" << this->index << "_on" << endl; }
void Testled_::off(void) { cout << "led" << index << "_off" << endl; }
int test0625005() {
  Testled led1, led2, led3;
  led1.index = 1;
  led2.index = 2;
  led3.index = 3;
  while (1) {
    //步骤1
    led1.on();
    led2.off();
    led3.off();
    usleep(1000 * 1000);
    //步骤2
    led1.off();
    led2.on();
    led3.off();
    usleep(1000 * 1000);
    //步骤3
    led1.off();
    led2.off();
    led3.on();
    usleep(1000 * 1000);
  }
  return 0;
}
  • 拓展分析和总结
    Linux中面向对象编程回顾
    华为LiteOS中面向对象编程回顾
    STM32 HAL库中面向对象编程回顾
    总结
    (1)面向对象是针对面向过程说的,编程时关注对象由“过程”转为“对象”
    (2)面向对象的外部表象就是一种组织代码,写程序的方式
    (3)面向对象的本质是一种封装数据和看待问题的更高层次的视角
    (4)面向对象是应对越来越复杂问题,是处理越来越庞大程序的更有效的方法
    (5)语言由非面向对象升级到面向对象是自然而然的成长,和人一样

总结

可以怎么去逐步去学习面向对象
任务变为对象,
任务的步骤变为各个对象的状态,并且注意需要什么方法实现
面向过程和面向对象是共存的
编程是由过程步骤关注对象状态,注意对象方法

学习记录,侵权联系删除。
来源:朱老师物联网大课堂

;