C++ 多态、重写、重载;子类析构问题

概念:

多态:基类指针执行基类对象时,就是使用基类的成员变量和函数,如果基类指针指向派生类对象时,就能够使用派生类的成员,这样的基类指针可按照多种形式来表现。

重写(override)、覆盖:子类重新定义父类中有相同名称参数虚函数,子类实现的函数 函数名称返回值入参及入参类型要完全与父类一样,不过访问修饰符可以变化,比如父类的是protected,子类可改为public或者其他。(多态,动态绑定

重载(overload):同一个类中,函数名相同,参数列表不同(参数类型或参数顺序不同)。(非多态,静态绑定

构成多态的条件:

       1.必须存在继承关系。

       2.继承关系中必须有同名的虚函数,遮蔽关系。

       3.有基类的指针,通过这个指针来调用虚函数。

以下是实验:

class MyParent
{
public:
	MyParent();
	virtual ~MyParent();
public:
	virtual void MyPrint(std::string str)
	{
		printf("This is Parent.\n");
	}
	void MyPrint(int nNum)
	{
		printf("This is int print.%d\n", nNum);
	}

private:
	int nA;
	int nB;
	int nC;
};

class ChildA : public MyParent
{
public:
	ChildA();
	ChildA(std::string str);
	~ChildA();
public:
	void MyPrint(std::string str)
	{
		std::cout << "This is childA:" << str.c_str() << std::endl;
		MyParent::MyPrint(str);//如果不调用父类的打印,则父类MyPrint函数不会执行。(函数的遮蔽)
	}
};

ChildA::ChildA()
{
	printf("This is Child A 构造\n");
}

ChildA::ChildA(std::string str)
{
	printf("This is Child A 带参构造\n");
}

ChildA::~ChildA()
{
	printf("This is Child A 析构\n");
}

MyParent::MyParent()
{
	nA = 1;
	nB = 1;
	nC = 1;
	printf("This is 父类构造\n");
}

MyParent::~MyParent()
{
	printf("This is 父类析构\n");
}

int main()
{
    MyParent* pp = new ChildA();
	pp->MyPrint("TEST");
	pp->MyPrint(100);
    delete pp;
    return 0;
}

结果为:构造函数执行顺序:父类 -> 子类。

 如果父类的析构未加virtual的话,那么直接delete pp,那么将会导致子类的析构不执行(如图2),造成内存泄漏的风险,解决办法就是父类的析构函数加上virtual,那么在delete的时候会先走子类的析构然后再走父类的析构。

图1:

C++ 多态、重写、重载;子类析构问题_第1张图片

图2:

C++ 多态、重写、重载;子类析构问题_第2张图片

你可能感兴趣的:(C++相关,多态)