当前位置:首页 > 公众号精选 > wenzi嵌入式软件
[导读]本文将叙述 C 的另一个内容,也就是抽象,这也是 C 相对于 C语言来说独特的一点。

前言

在上一则教程中,叙述了关于C 类型转换的相关内容,在本节教程中,将叙述 C 的另一个内容,也就是抽象,这也是 C 相对于 C语言来说独特的一点,下面我们就来着重叙述这一点。

纯虚函数

在介绍抽象类之前,需要弄明白何为纯虚函数,下面假定我们有这样一个需求:

做一个“各个国家的人的调查”,调查各个国家的人的:饮食、穿衣、开车

要完成这样一个事情,那我们现在就需要实现这样几个类,一个是 Human类,其他国家的人从 Human类里派生而来,就比如说是ChineseEnglishman,我们再回过头来想,我们所要实现的需求是调查各个国家的人,那么这个过程中,由Human类派生得到 Chinese和 Englishman,那么在实例化对象的时候,我们实际上是不会用到Human类去定义一个对象的,考虑到这层因素,我们在 Human类里使用到了纯虚函数的概念,类实现的代码如下所示:

class Human
{

private:
    int a;
public:
    /*纯虚函数*/
    virtual void eating(void) 0;
    virtual void wearing(void) 0;
    virtual void driving(void) 0;
};

class Englishman : public Human
{
public:
    void eating(void)  cout<<"use knife to eat"<<endl; }
    void wearing(void) {cout<<"wear english style"<<endl; }
    void driving(void) {cout<<"drive english car"<<endl; }
};

class Chinese : public Human 
{
public:
    void eating(void)  cout<<"use chopsticks to eat"<<endl; }
    void wearing(void) {cout<<"wear chinese style"<<endl; }
    void driving(void) {cout<<"drive chinese car"<<endl; }
};
我们可以看到在上述的代码中,Human类的成员函数跟前几讲所写的成员函数有所不同,而如上述 Human类的成员函数这般写法,也就被称之为是纯虚函数

抽象类

上述引出了纯虚函数的写法,那纯虚函数和抽象类之间有什么关系呢?实际上,抽象类就是具有纯虚函数的类,那这抽象类存在的意义是什么呢?总的来说,其作用也就是:向下定义好框架,向上提供统一的接口,其不能够实例化对象,基于上述几个类的前提下,我们编写主函数的代码:

int main(int argc,char **argv)
{
    Human h;

    return 0;
}
因为抽象类不能够实例化对象,所以上述代码编译结果是错误的,错误信息如下所示:

而使用通过抽象类派生得到的派生类实例化对象是可行的,代码如下所示:

int main(int argc, char** argv)
{
    Englishman e;
    Chinese    g;

    return 0;
}
另外需要注意的是:在派生抽象类的过程中,如果派生得到的子类没有覆写所有的纯虚函数,那么这个子类还是抽象类,比如有如下所示的代码,Human类沿用的是上述的写法,代码不变,如果我们将上述的 Chinese类进行更改,更改后的代码如下所示:

class Chinese : public Human 
{
public:
    void eating(void) cout<<"use chopsticks to eat"<<endl; }
    void wearing(void) {cout<<"wear chinese style"<<endl; }
    //void driving(void) {cout<<"drive chinese car"<
};
如上述代码所示,我们将 driving()函数注释掉了,那么也就是说,我们并没有将抽象类的全部纯虚函数进行覆写,那么当前这个Chinese类也是一个抽象类,也是不能够进行实例化对象的,要使得 Chinese类有作用,我们必须派生出来另一个类,代码如下所示:

class Guangximan : public Chinese 
{
    void driving(void) {cout<<"drive guangxi car"<<endl; }
};
这个时候,就可以用 Guangximan这个类来实例化对象了。

多文件编程

在前面的教程中,有一则教程说到了多文件编程,在 C 中也就是将类的声明放到头文件中,将类的实现放在.cpp文件中,为了更好地阐述这种方法,我们用实例来进行讲解,首先,来看一下,所涉及到地所有文件有哪些:

image-20210222103409774
可以看到上述有6个文件,我们首先来看 Chinese.h这个文件,代码如下所示:

#ifndef _CHINESE_H
#define _CHINESE_H

#include 
#include 
#include 

using namespace std;

class Chinese
{

public:
    void eating(void)
    void wearing(void);
    void drivering(void);
};

#endif
通过上述地.h文件可以看出,在这里的Chinese类中,它只涉及到类成员函数的一个声明,并没有成员函数的实现,我们继续来看Chinese.cpp的类实现:

#include "Chinese.h"

void Chinese::eating(void)
{
    cout << "use chopsticks to eat" << endl;
}

void Chinese::wearing(void)
{
    cout << "wear chinese style" << endl;
}

void Chinese::drivering(void)
{
    cout << "driver china car" << endl;
}
按照上述这样一种方法,我们继续来实现Englishman类中的代码,首先是Englishman.h中的代码,代码如下所示:

#ifndef _ENGLISHMAN_H
#define _ENGLISHMAN_H

#include 
#include 
#include 

using namespace std;

class Englishman
{

public:
    void eating(void);
    void wearing(void);
    void driver(void);
};

#endif
继续看.cpp中的代码,代码如下所示:

#include "Englishman.h"

void Englishman::eating(void)
{
    cout << "use chopsticks to eat" << endl;
}

void Englishman::wearing(void)
{
    cout << "wear chinese style" << endl;
}

void Englishman::drivering(void)
{
    cout << "driver china car" << endl;
}
至此,除了主函数以外的代码就编写完了,我们继续来看主函数的代码:

#include "Englishman.h"
#include "Chinese.h"

int main(int argc, char **argv)
{
    Englishman e;
    Chinese c;

    e.eating();
    c.eating();

    return 0;
}
在前面的教程中,我们就说过,如果是多文件的话,需要编写 Makefile文件,Makefile文件代码如下:

Human: main.o Chinese.o Englishman.o Human.o
    g  -o $@ $^

%.o : %.cpp
    g  -c -o $@ $<

clean:
    rm -f *.o Human 
上述代码就不再这里赘述了,跟之前教程中的 Makefile基本是一样的,有了Makefile之后,编译代码只需要使用 make命令就行了,编译结果如下所示:

image-20210222105051169
上述代码中,如果我们想要增添功能,比如说ChineseEnglishman都有名字,那么就可以增添设置名字和获取名字这两种方法,首先是 Chinese的代码,代码如下:

#ifndef _CHINESE_H
#define _CHINESE_H

#include 
#include 
#include 

using namespace std;

class Chinese{
private:
    char *name;
public:
    void setName(char *name);
    char *getName(void);
    void eating(void);
    void wearing(void);
    void driving(void);
    ~Chinese();
};

#endif
然后是.cpp中的代码:

#include "Chinese.h"

void Chinese::setName(char *name) 
{
    this->name = name;
}

char *Chinese::getName(void
{
    return this->name;
}

/*其他成员函数实现同上,这里省略*/
写完了 Chinese的代码,然后是Englishman中的代码,首先是Englishman.h中的代码:

#ifndef _ENGLISHMAN_H
#define _ENGLISHMAN_H

#include 
#include 
#include 

using namespace std;

class Englishman {
private:
    char *name;
public:
    void setName(char *name);
    char *getName(void);
    void eating(void);
    void wearing(void);
    void driving(void);
    ~Englishman();
};

#endif
紧接着,是.cpp中的代码:

#include "Englishman.h"

void Englishman::setName(char *name) 
{
    this->name = name;
}

char *Englishman::getName(void
{
    return this->name;
}
以这样的方式增添功能,确实是可行的,但是我们假设一下,如果类很多,除了中国人和英国人还有很多个国家的人,如果这些类都要增加相同的功能,这个工作量就比较大了,那要如何解决这个问题呢?这个时候,我们就可以引入一个新类Human,然后,将每个类相同的部分写在这个类里面,其他类,诸如EnglisnmanChinese就可以从Human类中继承而来,那这个时候,增添的操作,就只需要在 Human类中增加就好了,不需要改动ChineseEnglishman,工作量就小了很多。我们来看 Human类的代码实现,首先是.h代码的实现:

#ifndef _HUMAN_H
#define _HUMAN_H

#include 
#include 
#include 

using namespace std;

class Human {
private:
    char *name;

public:
    void setName(char *name);
    char *getName(void);    
};

#endif
然后是.cpp代码的实现:

#include "Human.h"

void Human::setName(char *name) 
{
    this->name = name;
}

char *Human::getName(void
{
    return this->name;
}
有了 Human类之后,我们就可以来实现我们所说的 EnglishmanChinese类了,代码如下所示:

#ifndef _ENGLISHMAN_H
#define _ENGLISHMAN_H

#include 
#include 
#include 

#include "Human.h"

using namespace std;

class Englishman : public Human 
{
public:
    void eating(void);
    void wearing(void);
    void driving(void);
    ~Englishman();
};

#endif
然后是Chinese的代码:

#ifndef _CHINESE_H
#define _CHINESE_H

#include 
#include 
#include 

#include "Human.h"

using namespace std;

class Chinese : public Human
{
public:
    void eating(void);
    void wearing(void);
    void driving(void);
    ~Chinese();
};

#endif
可以看到 EnglishmanChinese都是继承自Human类,这个时候,就不需要再自己实现setNamegetName了。

我们继续来完善我们的代码,先从主函数说起,主函数代码如下所示:

void test_eating(Human *h)
{
    h->eating();
}

int main(int argc, char **argv)
{
    Englishman e;
    Chinese c;

    Human * h[2] = {
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

嵌入式开发作为信息技术领域的重要分支,其涉及的语言种类繁多,各具特色。这些语言的选择取决于目标平台的特性、性能需求、开发者的熟练程度以及项目的具体要求。本文将详细介绍几种常见的嵌入式开发语言,包括C语言、C++、汇编语言...

关键字: 嵌入式开发 C语言

2023年10月18日,中国在第三届“一带一路”国际合作高峰论坛期间发布《全球人工智能治理倡议》,围绕人工智能发展、安全、治理三方面系统阐述了人工智能治理中国方案。

关键字: 人工智能 大模型 代码

学好电子技术基础知识,如电路基础、模拟电路、数字电路和微机原理。这几门课程都是弱电类专业的必修课程,学会这些后能保证你看懂单片机电路、知道电路的设计思路和工作原理;

关键字: 单片机 编程 电路设计

单片机编程需要使用专门的软件工具,这些工具能够帮助程序员编写、调试和烧录程序到单片机中。以下是一些常用的单片机编程软件:

关键字: 单片机 编程 软件工具

我们看到这么多的安全问题,部分原因在于我们对待安全的方式:安全性通常被认为是事后考虑的问题,是在开发结束时才添加到设备上的东西。然而,复杂的系统,尤其是嵌入式系统,有一个很大的攻击面,这让攻击者有机可乘,能够在“盔甲”上...

关键字: 代码 嵌入式系统 软件漏洞

Java语言和C语言是两种不同的编程语言,它们在语法、特性和应用领域上有许多差别。下面将详细介绍Java语言和C语言之间的差异以及它们各自的技术特点。

关键字: Java语言 C语言 编程

嵌入式系统是一种专门设计用于特定应用领域的计算机系统,它通常由硬件和软件组成,并且被嵌入到其他设备或系统中,以实现特定的功能。在嵌入式系统的开发过程中,选择适合的编程语言是至关重要的。C语言是一种被广泛应用于嵌入式系统开...

关键字: 嵌入式 计算机 C语言

C语言是一种广泛应用于软件开发领域的编程语言。它是由贝尔实验室的Dennis Ritchie在20世纪70年代初创建的,旨在为UNIX操作系统的开发提供一种高级编程语言。C语言具有简洁、高效、可移植性强等特点,因此成为了...

关键字: C语言 操作系统 应用程序

嵌入式系统是现代生活中无处不在的一部分。它们包括了我们的家电、汽车、智能手机、医疗设备等等。这些系统的工作必须高效、可靠,因为它们往往控制着生活中的关键方面。而C语言作为一种广泛用于嵌入式系统开发的编程语言,其质量和稳定...

关键字: 嵌入式系统 C语言 编程

在嵌入式系统开发领域中,C语言是使用最广泛的编程语言之一。它具有高效、灵活和可移植的特点,成为嵌入式系统设计师的首选语言。本文将介绍C语言编程的基本概念、特点以及在嵌入式系统开发中的应用。

关键字: 嵌入式系统 C语言 编程
关闭
关闭