精华内容
下载资源
问答
  • C语言实现继承的研究.pdf
  • C语言在嵌入式软件开发中被广泛使用,但由于开发人员和应用场景等原因,面向对象、设计模式等...面向对象是现在软件方法的根基,继承是面向对象的三大特性之一,本文结合C语言的特性,对使用C语言实现继承进行了讨论。
  • C语言实现继承和多态

    万次阅读 2016-08-13 16:17:46
    C语言实现继承和多态 继承和多态是面向对象语言最强大的功能。有了继承和多态,我们可以完成代码重用。在C中有许多技巧可以实现多态。本文的目的就是演示一种简单和容易的技术,在C中应用继承和多态。通过创建一个...

    C语言实现继承和多态

    继承和多态是面向对象语言最强大的功能。有了继承和多态,我们可以完成代码重用。在C中有许多技巧可以实现多态。本文的目的就是演示一种简单和容易的技术,在C中应用继承和多态。通过创建一个VTablevirtual table)和在基类和派生类对象之间提供正确的访问,我们能在C中实现继承和多态。VTable能通过维护一张函数表指针表来实现。为了提供基类和派生类对象之间的访问,我们可以在基类中维护派生类的引用和在派生类中维护基类的引用。

    2、说明

    C中实现继承和多态之前,我们应该知道类(Class)在C中如何表示。

    2.1、类在C中的表示

    考虑C++中的一个类"Person"

    //Person.h

    class Person

    {

    private:

        char* pFirstName;

        char* pLastName;

        

    public:

        Person(const char* pFirstName, const char* pLastName);    //constructor

        ~Person();    //destructor

     

        void displayInfo();

        void writeToFile(const char* pFileName);

     

    };

    C中表示上面的类,我们可以使用结构体,并用操作结构体的函数表示成员函数。

    //Person.h

    typedef struct _Person

    {

        char* pFirstName;

        char* pLastName;

    }Person;

     

    new_Person(const char* const pFirstName, const char* const pLastName);    //constructor

    delete_Person(Person* const pPersonObj);    //destructor

     

    void Person_DisplayInfo(Person* const pPersonObj);

    void Person_WriteToFile(Person* const pPersonObj, const char* const pFileName);

    这里,定义的操作结构体Person的函数没有封装。为了实现封装,即绑定数据、函数、函数指针。我们需要创建一个函数指针表。构造函数new_Person()将设置函数指针值以指向合适的函数。这个函数指针表将作为对象访问函数的接口。

    下面我们重新定义C中实现类Person

    //Person.h

     

    typedef struct _Person Person;

     

    //declaration of pointers to functions

    typedef void    (*fptrDisplayInfo)(Person*);

    typedef void    (*fptrWriteToFile)( Person*, const char*);

    typedef void    (*fptrDelete)( Person *) ;

     

    //Note: In C all the members are by default public. We can achieve

    //the data hiding (private members), but that method is tricky.

    //For simplification of this article

    // we are considering the data members     //public only.

    typedef struct _Person

    {

        char* pFName;

        char* pLName;

        //interface for function

        fptrDisplayInfo   Display;

        fptrWriteToFile   WriteToFile;

        fptrDelete      Delete;

    }Person;

     

    person* new_Person(const char* const pFirstName,

                       const char* const pLastName); //constructor

    void delete_Person(Person* const pPersonObj);    //destructor

     

    void Person_DisplayInfo(Person* const pPersonObj);

    void Person_WriteToFile(Person* const pPersonObj, const char* pFileName);

    new_Person()函数作为构造函数,它返回新创建的结构体实例。它初始化函数指针接口去访问其它成员函数。这里要注意的一点是,我们仅仅定义了那些允许公共访问的函数指针,并没有给定私有函数的接口。让我们看一下new_Person()函数或C中类Person的构造函数。

    //Person.c

    person* new_Person(const char* const pFirstName, const char* const pLastName)

    {

        Person* pObj = NULL;

        //allocating memory

        pObj = (Person*)malloc(sizeof(Person));

        if (pObj == NULL)

        {

            return NULL;

        }

        pObj->pFirstName = malloc(sizeof(char)*(strlen(pFirstName)+1));

        if (pObj->pFirstName == NULL)

        {

            return NULL;

        }

        strcpy(pObj->pFirstName, pFirstName);

     

        pObj->pLastName = malloc(sizeof(char)*(strlen(pLastName)+1));

        if (pObj->pLastName == NULL)

        {

            return NULL;

        }

        strcpy(pObj->pLastName, pLastName);

     

        //Initializing interface for access to functions

        pObj->Delete = delete_Person;

        pObj->Display = Person_DisplayInfo;

        pObj->WriteToFile = Person_WriteToFile;

     

        return pObj;

    }

    创建完对象之后,我们能够访问它的数据成员和函数。

    Person* pPersonObj = new_Person("Anjali", "Jaiswal");

    //displaying person info

    pPersonObj->Display(pPersonObj);

    //writing person info in the persondata.txt file

    pPersonObj->WriteToFile(pPersonObj, "persondata.txt");

    //delete the person object

    pPersonObj->Delete(pPersonObj);

    pPersonObj = NULL;

    注意:不像C++,在C中我们不能在函数中直接访问数据成员。在C++中,可以隐式通过“this”指针直接访问数据成员。我们知道C中是没有“this”指针的,通过显示地传递对象给成员函数。在C中为了访问类的数据成员,我们需要把调用对象作为函数参数传递。上面的例子中,我们把调用对象作为函数的第一个参数,通过这种方法,函数可以访问对象的数据成员。

    3、在C中类的表现

    Person类的表示——检查初始化接口指向成员函数:

    3.1、继承和多态的简单例子

    继承-Employee类继承自Person类:

     

    在上面的例子中,类Employee继承类Person的属性。因为DisplayInfo()WriteToFile()函数是virtual的,我们能够从Person的实例访问Employee对象中的同名函数。为了实现这个,我们创建Person实例的时候也初始化Employee类。多态使这成为可能。 在多态的情况下,去解析函数调用,C++使用VTable——即一张函数指针表。

    前面我们在结构体中维护的指向函数的指针接口的作用类似于VTable

    //Polymorphism in C++

    Person PersonObj("Anjali", "Jaiswal");

    Employee EmployeeObj("Gauri", "Jaiswal", "HR", "TCS", 40000);

     

    Person* ptrPersonObj = NULL;

        

    //preson pointer pointing to person object

    ptrPersonObj = &PersonObj;

    //displaying person info

    ptrPersonObj ->Display();

    //writing person info in the persondata.txt file

    ptrPersonObj ->WriteToFile("persondata.txt");

     

    //preson pointer pointing to employee object

    ptrPersonObj = &EmployeeObj;

    //displaying employee info

    ptrPersonObj ->Display();

    //writing empolyee info in the employeedata.txt file

    ptrPersonObj ->WriteToFile("employeedata.txt");

    C中,继承可以通过在派生类对象中维护一个基类对象的引用来完成。在基类实例的帮助下,women可以访问基类的数据成员和函数。然而,为了实现多态,街垒对象应该能够访问派生类对象的数据。为了实现这个,基类应该有访问派生类的数据成员的权限。

    为了实现虚函数,派生类的函数签名应该和基类的函数指针类似。即派生类函数将以基类对象的一个实例为参数。我们在基类中维护一个派生类的引用。在函数实现上,我们可以从派生类的引用访问实际派生类的数据。

    3.2、在C中结构体中的等效表示

    C中的继承-PersonEmployee结构体:

     

    如图所示,我们在基类结构体中声明了一个指针保存派生类对像,并在派生类结构体中声明一个指针保存基类对象。

    在基类对象中,函数指针指向自己的虚函数。在派生类对象的构造函数中,我们需要使基类的接口指向派生类的成员函数。这使我们可以通过基类对象(多态)灵活的调用派生类函数。更多细节,请检查PersonEmployee对象的构造函数。

    当我们讨论C++中的多态时,有一个对象销毁的问题。为了正确的清楚对象,它使用虚析构函数。在C中,这可以通过使基类的删除函数指针指向派生类的析构函数。派生类的析构函数清楚派生类的数据和基类的数据和对象。注意:检查例子的源码中,实现须构造函数和虚函数的实现细节。

    创建Person对象

    //Person.h

     

    typedef struct _Person Person;

     

    //pointers to function

    typedef void    (*fptrDisplayInfo)(Person*);

    typedef void    (*fptrWriteToFile)(Person*, const char*);

    typedef void    (*fptrDelete)(Person*) ;

     

    typedef struct _person

    {

        void* pDerivedObj;

        char* pFirstName;

        char* pLastName;

        fptrDisplayInfo Display;

        fptrWriteToFile WriteToFile;

        fptrDelete        Delete;

    }person;

     

    Person* new_Person(const char* const pFristName,

                       const char* const pLastName);    //constructor

    void delete_Person(Person* const pPersonObj);    //destructor

     

    void Person_DisplayInfo(Person* const pPersonObj);

    void Person_WriteToFile(Person* const pPersonObj, const char* const pFileName);

        

    //Person.c

    //construction of Person object

    Person* new_Person(const char* const pFirstName, const char* const pLastName)

    {

        Person* pObj = NULL;

        //allocating memory

        pObj = (Person*)malloc(sizeof(Person));

        if (pObj == NULL)

        {

            return NULL;

        }

        //pointing to itself as we are creating base class object

        pObj->pDerivedObj = pObj;

        pObj->pFirstName = malloc(sizeof(char)*(strlen(pFirstName)+1));

        if (pObj->pFirstName == NULL)

        {

            return NULL;

        }

        strcpy(pObj->pFirstName, pFirstName);

     

        pObj->pLastName = malloc(sizeof(char)*(strlen(pLastName)+1));

        if (pObj->pLastName == NULL)

        {

            return NULL;

        }

        strcpy(pObj->pLastName, pLastName);

     

        //Initializing interface for access to functions

        //destructor pointing to destrutor of itself

        pObj->Delete = delete_Person;

        pObj->Display = Person_DisplayInfo;

        pObj->WriteToFile = Person_WriteToFile;

     

        return pObj;

    }

    Person对象的结构

    创建Employee对象

    //Employee.h

     

    #include "Person.h"

     

     

    typedef struct _Employee Employee;

     

    //Note: interface for this class is in the base class

    //object since all functions are virtual.

    //If there is any additional functions in employee add

    //interface for those functions in this structure

    typedef struct _Employee

    {

        Person* pBaseObj;

        char* pDepartment;

        char* pCompany;

        int nSalary;

        //If there is any employee specific functions; add interface here.

    }Employee;

     

    Person* new_Employee(const char* const pFirstName, const char* const pLastName,

            const char* const pDepartment, const char* const pCompany,

            int nSalary);    //constructor

    void delete_Employee(Person* const pPersonObj);    //destructor

     

    void Employee_DisplayInfo(Person* const pPersonObj);

    void Employee_WriteToFile(Person* const pPersonObj, const char* const pFileName);

        

    //Employee.c

    Person* new_Employee(const char* const pFirstName, const char* const pLastName,

                         const char* const pDepartment,

                         const char* const pCompany, int nSalary)

    {

        Employee* pEmpObj;

        //calling base class construtor

        Person* pObj = new_Person(pFirstName, pLastName);

        //allocating memory

        pEmpObj = malloc(sizeof(Employee));

        if (pEmpObj == NULL)

        {

            pObj->Delete(pObj);

            return NULL;

        }

        pObj->pDerivedObj = pEmpObj; //pointing to derived object

        

        //initialising derived class members

        pEmpObj->pDepartment = malloc(sizeof(char)*(strlen(pDepartment)+1));

        if(pEmpObj->pDepartment == NULL)

        {

            return NULL;

        }

        strcpy(pEmpObj->pDepartment, pDepartment);

        pEmpObj->pCompany = malloc(sizeof(char)*(strlen(pCompany)+1));

        if(pEmpObj->pCompany== NULL)

        {

            return NULL;

        }

        strcpy(pEmpObj->pCompany, pCompany);

        pEmpObj->nSalary = nSalary;

            

        //Changing base class interface to access derived class functions

        //virtual destructor

        //person destructor pointing to destrutor of employee

        pObj->Delete = delete_Employee;

        pObj->Display = Employee_DisplayInfo;

        pObj->WriteToFile = Employee_WriteToFile;

     

        return pObj;

    }

    Employee对象的结构

    注意:从基类函数到派生类函数改变了接口(VTable)中指针位置。现在我们可以从基类(多态)访问派生类函数。我们来看如何使用多态。

    Person* PersonObj = new_Person("Anjali", "Jaiswal");

    Person* EmployeeObj = new_Employee("Gauri", "Jaiswal","HR", "TCS", 40000);

     

    //accessing person object

     

    //displaying person info

    PersonObj->Display(PersonObj);

    //writing person info in the persondata.txt file

    PersonObj->WriteToFile(PersonObj,"persondata.txt");

    //calling destructor

    PersonObj->Delete(PersonObj);

     

    //accessing to employee object

     

    //displaying employee info

    EmployeeObj->Display(EmployeeObj);

    //writing empolyee info in the employeedata.txt file

    EmployeeObj->WriteToFile(EmployeeObj, "employeedata.txt");

    //calling destrutor

    EmployeeObj->Delete(EmployeeObj);

    结论

    使用上面描述的简单的额外代码能是过程式C语言有多态和继承的特性。我们简单的使用函数指针创建一个VTable和在基类和派生类对象中交叉维护引用。用这些简单的步骤,我们在C中可以实现继承和多态。

     

    展开全文
  • c语言实现继承与多态 具体要求: 利用c语言实现一个struct A与struct B 包含一个int成员a与b,要求实现B继承A的效果,即B中包含A,再者,可实现多态,即A* p指向A调用A的函数,指向B调用B的函数 c++的继承与多态...
    c语言实现继承与多态
    具体要求:
    利用c语言实现一个struct A与struct B 包含一个int成员a与b,要求实现B继承A的效果,即B中包含A,再者,可实现多态,即A* p指向A调用A的函数,指向B调用B的函数

    c++的继承与多态实现:

    #include <iostream>
    using namespace std;
    #include <windows.h>
    class A
    {
    public:
        virtual void f1()
        {
            cout << "A::f()" << endl;
        }
    
        int _a;
    };
    
    class B : public A
    {
    public:
        virtual void f1()//重写
        {
            cout << "B::f()" << endl;
        }
    
        int _b;
    };
    
    
    int main()
    {
    
        A a;
        B b;
    
        A* p = &a;//指向A
        p->f1();
        p = &b;
        p->f1();
        system("pause");
        return 0;
    }
    

    这里写图片描述

    c语言实现:

    typedef void(*FUNC) ();//定义函数指针
    struct A
    {
        FUNC _f;//利用函数指针实现含有成员函数
        int a;
    };
    struct B
    {
        struct A a;//利用嵌套实现继承
        int b;
    };
    
    void funA()
    {
        printf("A::fun\n");
    }
    void funB()
    {
        printf("B::fun\n");
    }
    int main()
    {
        struct A a;
        struct B b;
        a._f = funA;
        b.a._f = funB;
        struct A *p = &a;//指向struct A a
        p->_f();
        p = (struct A*)&b;
        p->_f();
    
    
        system("pause");
        return 0;
    }

    这里写图片描述

    展开全文
  • 经典面试题:C语言实现继承和多态

    千次阅读 2018-04-21 21:20:12
    C语言实现继承和多态 实现要求如下: C 实现一个 struct A 和 stuct B 包含一个 int 成员 a 和 b,要求达到B 继承 A 的效果,也就是 B里面包含一个 A,并且能达到多态的效果,也就是一个 A* p 指向一个指向A 调...

    题目:

    C语言实现继承和多态
    实现要求如下:
    C 实现一个 struct A 和 stuct B 包含一个 int 成员 a 和 b,要求达到B 继承 A 的效果,也就是 B里面包含一个 A,并且能达到多态的效果,也就是一个 A* p 指向一个指向A 调的是 A 的函数,指向 B 调的是 B 的函数
    具体效果如下图:

    #include <iostream>
    using namespace std;
    
    class A
    {
    public:
        virtual void fun()
        {
            printf("A::fun()\n");
        }
        int _a;
    };
    
    class B:public A
    {
    public:
        virtual void fun()
        {
            printf("B::fun()\n");
        }
        int _b;
    };
    
    int main()
    {
        A a;
        B b;
        A* p = &a;
        p->fun();
        p = &b;
        p->fun();
    
        return 0;
    }

    这里写图片描述

    代码如下:

    #include <stdio.h>
    
    typedef void(*FUN) ();//定义函数指针
    
    struct A
    {
        FUN _f;//C语言的结构体不支持成员函数,只能用函数指针来实现“含有成员函数”
        int _a;
    };
    
    struct B
    {
        struct A a;//C语言不支持继承,只能用嵌套结构体实现“B继承A”
        int _b;
    };
    
    void funA()
    {
        printf("A::fun\n");
    }
    void funB()
    {
        printf("B::fun\n");
    }
    
    int main()
    {
        struct A a;
        struct B b;
        a._f = funA;
        b.a._f = funB;
        struct A* p = &a;
        p->_f();
        p = (struct A*)&b;
        p->_f();
    
        return 0;
    }

    这里写图片描述

    展开全文
  • C语言实现继承多态

    千次阅读 2020-10-08 21:59:27
    #include <string.h> #include <stdio.h> struct animal{ char name[20]; void (*speak)(); }; void Animal(struct animal *this, const char *name, void(*fun)()){ strcpy(this->...struct
    #include <string.h>
    #include <stdio.h>
    struct animal{
            char name[20];
            void (*speak)();
    };
    void Animal(struct animal *this, const char *name, void(*fun)()){
            strcpy(this->name, name);
            this->speak=fun;
    }
    struct cat{
            struct animal base;
    };
    void catSpeak(){
            printf("Mmmmiao~\n");
    }
    void Cat(struct cat *this){
            Animal((struct animal *)this, "cat's Name is GuaGua!!!", catSpeak);
    }
    int main(){
            struct cat c;
            Cat(&c);
            struct animal *p = (struct animal *)&c;
            p->speak();
            printf("%s",p->name);
    }
    
    

    输出结果:

    (base) ➜  POLYMORPHISMbyC ./INHERI                
    Mmmmiao~
    cat's Name is GuaGua!!!%  
    

    完整来源:
    https://zhuanlan.zhihu.com/p/25127633

    展开全文
  • C语言实现继承与多态

    2017-04-18 19:21:54
    在前面博客已经详细讲过C++中继承与多态的概念,在这里则只使用C语言的语法来实现继承与多态。 继承: 即派生类中拥有基类的成员变量和成员函数,所以C语言实现如下: #include typedef void(*Func)(void); void...
  • c语言实现继承和多态

    2017-08-04 19:18:22
    继承 概念:继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能。这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现由简单到...
  • 用struct来模拟实现,因为struct在C和C++中都能可以使用,在C中称为结构体在C++中称为类,但他们的原理是一样的,又因为struct的限定符默认是公有的,在C中没有限定符这个概念,所以用C语言只能
  • c语言实现继承与多态

    2010-05-03 22:13:42
    虽然面向对象的设计并不会在很大程度上依赖于某种语言,但现代著作中提及面向对象的实现一般都认为是C++, Smalltalk, 或者Java。 本文从较底层的视角用面向过程的语言(比如C)对面向对象予以实现,这对于一些想运用...
  • 利用C语言实现C++里面的继承和多态特性 先来看看C++里面的继承和多态: 代码: class A { public: virtual void fun() { printf("A::fun()\n"); } int _a; }; class B :public A//B继承A { pu....
  • C语言实现继承和多态 实现要求如下: C 实现一个 struct A 和 stuct B 包含一个 int 成员 a 和 b, 要求达到B 继承 A 的效果,也就是 B里面包含一个 A,并且能达到多态的效果, 也就是一个 A* p 指向一个指向A 调的...
  • C语言实现简单封装继承机制

    万次阅读 2016-02-21 12:09:53
    0 继承是OO设计的基础继承是OO设计中的基本部分,也是实现多态的基础,C++,C#,Objective-C,...下面我们就来看看如何用C语言实现继承。1 内存布局层面上继承的含义如今几乎所有程序员都知道继承的抽象含义,对于被用
  • C语言实现C++继承与多态
  • 本文主要给大家简单讲诉了C和C++的区别以及如何使用C语言模拟实现C++继承和多态,并附上示例代码,是篇相当不错的文章,推荐给喜欢C语言的小伙伴们
  • c语言实现c++继承模型

    2018-05-01 21:14:38
    要用c语言实现c++继承模型,首先需要回顾一些关于类,继承相关的理论知识:1. class的本质仍是struct, 在内存中class依旧可以看作变量的集合,每个对象有独立的成员变量,所有对象共享类中的成员函数, 类中的成员...
  • C语言实现对象编程之继承代码,总共包含两种方式的代码,代码非常详细,可以在Linux平台和Windows平台编译执行。
  • C语言实现封装、继承和多态

    千次阅读 2016-03-19 10:57:15
    C语言实现封装、继承和多态–通过创建一个VTable(virtual table)和在基类和派生类对象之间提供正确的访问 如何实现 C 语言的继承和多态–通过函数指针来实现的继承与多态,简单明了,animal基类,cat,dog两个...
  • 00. 目录 文章目录00. 目录01. 概述02. 利用结构体包含实现继承功能03. 利用私有指针实现继承...第一种是利用数据结构的包含实现继承功能,第二种是利用私有指针实现继承功能,它们提供的接口是完全一致的,只是在实现
  • 继承 继承就是当创建一个类时,不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一... 继承实现实现使用了组合的方式,即把基类作为派生类的成员变量之一。 但是一定要将基类放在派生类首部,...
  • 利用结构体包含实现继承功能03. 利用私有指针实现继承功能04. 总结05. 附录01. 概述面向对象编程具有封装性、继承性、多态性三个基本特性。使用C语言可以实现基于对象的编程。在基于对象编程实现封装的基础之上,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 80,046
精华内容 32,018
关键字:

c语言实现继承

c语言 订阅