Inheritance and Polymorphism in C

Source: Internet
Author: User
Tags define function

Inheritance and Polymorphism in C
1. Introduction

Inheritance and polymorphism are the most powerful functions of object-oriented languages. With inheritance and polymorphism, We can reuse code. There are many techniques in C to achieve polymorphism. The purpose of this article is to demonstrate a simple and easy technology that applies inheritance and Polymorphism in C. By creating a VTable and providing correct access between the base class and the derived class object, we can implement inheritance and Polymorphism in C. VTable can be implemented by maintaining a function table. To provide access between the base class and the object of the derived class, we can maintain the reference of the derived class in the base class and the reference of the base class in the derived class.

2. Description

Before implementing inheritance and Polymorphism in C, we should know how classes are represented in C.

2.1 representation of classes in C

Consider a class "Person" in C ++ ".

//Person.hclass Person{private:    char* pFirstName;    char* pLastName;    public:    Person(const char* pFirstName, const char* pLastName);    //constructor    ~Person();    //destructor    void displayInfo();    void writeToFile(const char* pFileName);};

In C, it indicates the above class. We can use struct and use the function that operates the struct to represent member functions.

//Person.htypedef struct _Person{    char* pFirstName;    char* pLastName;}Person;new_Person(const char* const pFirstName, const char* const pLastName);    //constructordelete_Person(Person* const pPersonObj);    //destructorvoid Person_DisplayInfo(Person* const pPersonObj);void Person_WriteToFile(Person* const pPersonObj, const char* const pFileName);

 

Here, the Person function of the defined operation struct is not encapsulated. To implement encapsulation, Data, functions, and function pointers are bound. We need to create a function pointer table. The constructor new_Person () will set the function pointer value to point to the appropriate function. This function is used as an interface for accessing functions.

Next we will redefine the implementation class Person in C.

//Person.htypedef struct _Person Person;//declaration of pointers to functionstypedef 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); //constructorvoid delete_Person(Person* const pPersonObj);    //destructorvoid Person_DisplayInfo(Person* const pPersonObj);void Person_WriteToFile(Person* const pPersonObj, const char* pFileName);

The new_Person () function acts as the constructor and returns the newly created struct instance. It initializes the function pointer interface to access other member functions. Note that we only define function pointers that allow public access and do not specify private function interfaces. Let's take a look at the new_Person () function or the Person-class constructor in C.

//Person.cperson* 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;}

 

After an object is created, we can access its data members and functions.

Person* pPersonObj = new_Person("Anjali", "Jaiswal");//displaying person infopPersonObj->Display(pPersonObj);//writing person info in the persondata.txt filepPersonObj->WriteToFile(pPersonObj, "persondata.txt");//delete the person objectpPersonObj->Delete(pPersonObj);pPersonObj = NULL;

Note: Unlike C ++, in C, we cannot directly access data members in functions. In C ++, you can use the "this" pointer to access data members directly. We know that there is no "this" pointer in C, and the object is passed to the member function through display. In C, for the data member of the callback class, we need to pass the called object as a function parameter. In the above example, we use the called object as the first parameter of the function. Through this method, the function can access the data members of the object.

3. Performance of classes in C

The representation of the Person class -- check whether the initialization interface points to the member function:

3.1 simple examples of inheritance and Polymorphism

Inheritance-the Employee class inherits from the Person class:

In the preceding example, class Employee inherits the attributes of class Person. Because the DisplayInfo () and WriteToFile () functions are virtual, we can access the functions of the same name in the Employee object from the Person instance. To achieve this, we also initialize the Employee class when creating the Person instance. Polymorphism makes this possible. In the case of polymorphism, the function call is parsed, and C ++ uses VTable, that is, a function finger table.

The pointer interface previously maintained in the struct to the function is similar to VTable.

//Polymorphism in C++Person PersonObj("Anjali", "Jaiswal");Employee EmployeeObj("Gauri", "Jaiswal", "HR", "TCS", 40000);Person* ptrPersonObj = NULL;    //preson pointer pointing to person objectptrPersonObj = &PersonObj;//displaying person infoptrPersonObj ->Display();//writing person info in the persondata.txt fileptrPersonObj ->WriteToFile("persondata.txt");//preson pointer pointing to employee objectptrPersonObj = &EmployeeObj;//displaying employee infoptrPersonObj ->Display();//writing empolyee info in the employeedata.txt fileptrPersonObj ->WriteToFile("employeedata.txt");

In C, inheritance can be completed by maintaining a reference to a base class object in the derived class object. With the help of a base class instance, women can access the data members and functions of the base class. However, to achieve polymorphism, the street base object should be able to access the data of the derived class object. To achieve this, the base class should have the permission to access the data members of the derived class.

To implement virtual functions, the function signature of the derived class should be similar to the function pointer of the basic class. That is, the derived class function takes an instance of the base class object as the parameter. We maintain the reference of a derived class in the base class. In function implementation, we can access the data of the actual derived class from the reference of the derived class.

3.2 equivalent representation of struct in C

Inheritance-Person and Employee struct in C:

In the base class struct, we declare a pointer to save the object of the derived class, and declare a pointer to save the base class object in the structure of the derived class.

In a base class object, the function pointer points to its own virtual function. In the constructor of a derived class object, we need to point the base class interface to the member function of the derived class. This allows us to flexibly call derived class functions through base class objects (polymorphism. For more details, check the constructor of the Person and Employee objects.

When we discuss polymorphism in C ++, there is a problem of object destruction. To correctly understand the object, it uses a virtual destructor. In C, you can point the deletion function pointer of the base class to the destructor of the derived class. The destructor of a derived class is clear about the data and objects of the derived class and the base class. Note: Check the Implementation Details of constructor and virtual function in the source code of the example.

Create Person object
//Person.htypedef struct _Person Person;//pointers to functiontypedef 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);    //constructorvoid delete_Person(Person* const pPersonObj);    //destructorvoid Person_DisplayInfo(Person* const pPersonObj);void Person_WriteToFile(Person* const pPersonObj, const char* const pFileName);    //Person.c//construction of Person objectPerson* 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;}
Structure of the Person object

Create an Employee object
//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);    //constructorvoid delete_Employee(Person* const pPersonObj);    //destructorvoid Employee_DisplayInfo(Person* const pPersonObj);void Employee_WriteToFile(Person* const pPersonObj, const char* const pFileName);    //Employee.cPerson* 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;}
Structure of the Employee object

Note: The function from the base class function to the derived class function changes the pointer position in the interface (VTable. Now we can access the function of the derived class from the base class (polymorphism. Let's look at how to use polymorphism.

Person* PersonObj = new_Person("Anjali", "Jaiswal");Person* EmployeeObj = new_Employee("Gauri", "Jaiswal","HR", "TCS", 40000);//accessing person object//displaying person infoPersonObj->Display(PersonObj);//writing person info in the persondata.txt filePersonObj->WriteToFile(PersonObj,"persondata.txt");//calling destructorPersonObj->Delete(PersonObj);//accessing to employee object//displaying employee infoEmployeeObj->Display(EmployeeObj);//writing empolyee info in the employeedata.txt fileEmployeeObj->WriteToFile(EmployeeObj, "employeedata.txt");//calling destrutorEmployeeObj->Delete(EmployeeObj);
Conclusion

The simple extra code described above can be a procedural C language with polymorphism and inheritance features. We simply use function pointers to create a VTable and cross-maintain references in the base class and derived class objects. With these simple steps, we can implement inheritance and Polymorphism in C.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.