C + + virtual functions and polymorphism

Keywords: C++ linq p2p

one   virtual function

        one point one   definition   The member function decorated with virtual is called   virtual function

        one point two   Impact on class memory

                An empty class (there is no data member in the class, and the member function does not occupy memory) occupies 1 byte

                        Virtual functions occupy 4 bytes (32 bits), that is, the size of a pointer

                        No matter how many virtual functions there are, they occupy 4 bytes.

                Out of class implementations do not require virtual modifiers

#include<iostream>
using namespace std;
class A
{
public:
	void print() {}
protected:
};
class B
{
public:
	virtual void print() {}
protected:
};
void testVitrual()
{
	cout << sizeof(B) << endl;
}
void testA()
{
	cout << sizeof(A )<< endl;
}

int main()
{
	testA();
	testVitrual();

	return 0;
}

        one point three   Virtual function table

                Is a pointer that stores the first address of all virtual functions.

#include<iostream>
using namespace std;
class A
{
public:
	virtual void print1() {cout<<"Virtual function 1"<<endl;}
	virtual void print2() { cout << "Virtual function 2" << endl; }
	virtual void print3() {}
protected:
};

void testA()
{
	A a;
	int** vptr = (int**)&a;
	typedef void(*PF)();
	PF func = (PF)vptr[0][0];
	func();
	func = (PF)vptr[0][1];
	func();
}

int main()
{
	testA();
	return 0;
}

  two   polymorphic

        two point one   definition   The same behavior (call) leads to different   Results

        two point two   Principle of necessity

                There must be a virtual function in the parent class (whether the child class has virtual or not, but there must be a function with the same name)

                Subclasses must adopt public inheritance

                There must be a reference to the pointer (use)

#include <iostream>
using namespace std;
class Man
{
public:
	void print1()
	{
		cout << "Lang" << endl;
	}
	virtual void print2()   //Parent class must have virtual
	{
		cout << "Ah Lang" << endl;
	}
protected:
};
class Sister :public Man
{
public:
	void print1()
	{
		cout << "A Mei" << endl;
	}
	void print2()
	{
		cout << "Ah Mei" << endl;
	}
protected:

};
void testVirtual()
{
	//There is no polymorphism in normal access
	cout << "Normal access, proximity principle" << endl;
	Man  man;
	man.print1();
	man.print2();
	Sister woman;
	woman.print1();
	woman.print2();
	cout << "Pointer access,Normal assignment" << endl;
	Man* pm = new Man;
	pm->print1();
	pm->print2();
	Sister* pw = new Sister;
	pw->print1();
	pw->print2();
	cout << "Pointer abnormal assignment:The subclass object initializes the parent class pointer" << endl;
	Man* parent = new Sister;
	//There is virtual to see the object type, and there is no virtual to see the pointer
	parent->print1();			//Not a virtual function
	parent->print2();			//Is a subclass of a virtual function call
	parent = new Man;
	parent->print2();		//Call parent class 			 Different from 51 lines of the same behavior
}


//What about the unified interface function
void printInfo(Man* parent)
{
	parent->print2();
}

int main()
{
	testVirtual();
	printInfo(new Sister);

	return 0;
}

        two point three   Polymorphic application

                 Reduce code changes due to changes
                 Meet new requirements by adding code

#include <iostream>
using namespace std;

class Shape
{
public:
	virtual void Draw()
	{
		cout << "Drawing process" << endl;
	}
protected:
};
class Rect :public Shape
{
public:
	void Draw()
	{
		cout << "Draw rectangle" << endl;
	}
protected:

};
class Circle :public Shape
{
public:
	void Draw()
	{
		cout << "Draw a circle" << endl;
	}
protected:

};
class Triangle :public Shape
{
public:
	void Draw()
	{
		cout << "Draw triangle" << endl;
	}
};
class Ellipse :public Shape
{
public:
	void Draw()
	{
		cout << "Draw ellipse" << endl;
	}
};
//Reduce code changes due to changes
//Meet new requirements by adding code
//Unified interface
class Tool
{
public:
	void draw(Shape* parent)
	{
		parent->Draw();
	}
};
int main()
{

	Tool* pTool = new Tool;
	pTool->draw(new Circle);
	pTool->draw(new Rect);
	pTool->draw(new Triangle);
	pTool->draw(new Ellipse);


	return 0;
}

three   Pure virtual function  

        Pure virtual functions are also virtual functions, but pure virtual functions have no function body

        three point one   Writing method

virtual void print()=0;

        3.2 abstract classes

        A class with at least one pure virtual function is called an abstract class

                Abstract classes cannot build objects

                Abstract classes can construct object pointers

                As like as two peas, the subclass rewrite function must be exactly the same as the parent class.

                 Subclasses that want to create objects must override the pure virtual functions of the parent class

                        Other functions and members can be added

        Pure virtual functions are not rewritten, no matter how many times they are inherited   Are pure virtual functions

        Virtual functions are inherited no matter how many times   virtual function

four   Virtual deconstruction

         When initializing the parent class pointer with a subclass object, in order to ensure that the subclass object can be released, the destructor of the parent class needs to be modified with virtual

#include<iostream>
using namespace std;

class parent
{
public:
	
	virtual ~parent()	
	{
		cout << "Parent class destructor" << endl;
	}
protected:
};

class son :public parent
{
public:
	~son()
	{
		cout << "Subclass deconstruction" << endl;
	}
};


int main()
{
	//The subclass object initializes the parent class pointer, and the parent class needs virtual destruct to release memory
	parent* pp = new son;
	delete pp;	//The parent class is not a virtual destructor, which means that the child class cannot free memory;

	return 0;
}

Posted by elgordo1960 on Sat, 04 Dec 2021 20:04:53 -0800