Lesson 51 C++ Object Model Analysis

Keywords: less

The content of this paper comes from the learning summary of C++ in-depth analysis course for Tang Zolin Teacher of Diday College

Inheritance Object Model

Internal classes in C++ compilers can be understood as structs
Subclasses are derived by superimposing new members of subclasses on members of the parent class

Let's write a program to verify

#include <iostream>

using namespace std;

class Parent
{
protected:
	int m_i;
	int m_j;
};

class Child : public Parent
{
public:
	int m_k;
};

int main()
{
	cout << "sizeof(Parent) = " << sizeof(Parent) << endl;
	cout << "sizeof(Child) = " << sizeof(Child) << endl;

	return 0;
}

Run Results

The result of the experiment is that the subclass inherits the memory space of the parent member variable




Implementation principle of C++ polymorphism

When a virtual function is declared in a class, the compiler generates a table of virtual functions in the class
A virtual function table is a data structure that stores the address of a member function
Virtual function tables are automatically generated and maintained by the compiler
Virtual member functions are put into the virtual function table by the compiler
When virtual functions exist, each object has a pointer to the virtual function table





Here we use C to implement polymorphism according to the principle of polymorphism implementation.
Simulate classes through structs, subclasses through struct inclusions to simulate inheritance relationships, and ultimately polymorphism through function pointers
Demo.h

#ifndef _DEMO_H_
#define _DEMO_H_


typedef void Demo;

Demo *Demo_Creat(int i, int j);
int Demo_GetI(Demo *pthis);
int Demo_GetJ(Demo *pthis);
void Demo_Free(Demo *pthis);
int Demo_Add(Demo *pthis, int val);


typedef void Derived;

Derived *Derived_Creat(int i, int j, int k);
int Derived_GetI(Demo *pthis);
int Derived_GetJ(Demo *pthis);
int Derived_GetK(Demo *pthis);
int Derived_add(Derived *pthis, int val);

#endif

Demo.c

#include <stdio.h>
#include <malloc.h>
#include "Demo.h"



struct DemoClass
{
	struct VTable *pVtl;
	int m_i;
	int m_j;
};

struct DerivedClass
{
	struct DemoClass d;
	int m_k;
};


/* Virtual List*/
struct VTable 
{
	int (*pAdd)(void *, int);
};

static int Demo_Virtual_Add(Demo *pthis, int val);
static int Derived_Virtual_Add(Derived *pthis, int val);

/*List of parent virtual functions */
static struct VTable g_DemoVtal = {
	Demo_Virtual_Add
};

/* Subclass virtual function list */
static struct VTable g_Virtual_Derived = {
	Derived_Virtual_Add
};




Demo* Demo_Creat(int i, int j)
{
	struct DemoClass *pthis = (struct DemoClass *)malloc(sizeof(struct DemoClass));
	if(pthis == NULL)
		return NULL;

	pthis->pVtl = &g_DemoVtal;
	pthis->m_i = i;
	pthis->m_j = j;

	return pthis;
}

int Demo_GetI(Demo *pthis)
{
	struct DemoClass *demo = (struct DemoClass *)pthis;
	return demo->m_i;
}

int Demo_GetJ(Demo *pthis)
{
	struct DemoClass *demo = (struct DemoClass *)pthis;
	return demo->m_j;
}

static int Demo_Virtual_Add(Demo *pthis, int val)
{
	struct DemoClass *demo = (struct DemoClass *)pthis;

	return (demo->m_i + demo->m_j + val);
}

int Demo_Add(Demo *pthis, int val)
{
	struct DemoClass *demo = (struct DemoClass *)pthis;

	return demo->pVtl->pAdd(pthis, val);
}

void Demo_Free(Demo *pthis)
{
	free(pthis);
}

Derived *Derived_Creat(int i, int j, int k)
{
	struct DerivedClass *Derv = (struct DerivedClass *)malloc(sizeof(struct DerivedClass));

	Derv->d.pVtl = &g_Virtual_Derived;
	Derv->d.m_i = i;
	Derv->d.m_j = j;
	Derv->m_k = k;

	return Derv;
}

int Derived_GetI(Demo *pthis)
{
	struct DerivedClass *Derv = (struct DerivedClass *)pthis;
	return Derv->d.m_i; 
}

int Derived_GetJ(Demo *pthis)
{
	struct DerivedClass *Derv = (struct DerivedClass *)pthis;
	return Derv->d.m_j; 
}

int Derived_GetK(Demo *pthis)
{
	struct DerivedClass *Derv = (struct DerivedClass *)pthis;
	return Derv->m_k; 
}

static int Derived_Virtual_Add(Derived *pthis, int val)
{
	struct DerivedClass *Derv = (struct DerivedClass *)pthis;

	return (Derv->d.m_i + Derv->d.m_j + Derv->m_k + val);
}

int Derived_add(Derived *pthis, int val)
{
	struct DerivedClass *Derv = (struct DerivedClass *)pthis;

	return Derv->d.pVtl->pAdd(pthis, val);
}

main.c

#include <stdio.h>
#include "Demo.h"

void run(Demo *pthis, int val)
{
	int ret = Demo_Add(pthis, val);
	printf("run: ret = %d\n", ret);
}

int main(void)
{
	Demo *classdemo = Demo_Creat(1, 2);

	int i = Demo_GetI(classdemo);
	int j = Demo_GetJ(classdemo);

	printf("i = %d\n", i);
	printf("j = %d\n", j);

	Derived *classderived = Derived_Creat(10, 20, 30);

	int ret = Demo_Add(classdemo, 3);
	printf("Demo_Add: ret = %d\n", ret);

	ret = Derived_add(classderived, 40);
	printf("Derived_add: ret = %d\n", ret);

	run(classdemo, 3);
	run(classderived, 40);

	Demo_Free(classderived);
	Demo_Free(classdemo);

	return 0;
}

Run result:

The experimental results show that the run function achieves the polymorphic feature and the corresponding object function is implemented by the introduction of object pointers of parent and child classes.



Summary

Inheritance is essentially the overlay of member variables between parents and children
Polymorphisms in C++ are implemented through virtual function tables
Virtual function tables are automatically generated and maintained by the compiler
Virtual functions are less efficient to call than normal member functions

Forty-seven original articles were published, 0 were praised, 1289 visited
Private letter follow

Posted by zwxetlp on Sat, 29 Feb 2020 18:31:09 -0800