多态1...

多态的概念

通俗来说就是多种形态,具体就是去完成某个行为,当不同的对象去完成时会产生出不同的状态

多态两个条件:

1、子类重写父类的虚函数
2、必须是父类的指针或者引用去调用虚函数(指向谁就调用谁的虚函数)

class Person
{
public:
	virtual void BuyTicket()//虚函数
	{
		cout << "正常排队-全价买票" << endl;
	}
protected:
	int _age;
	string _name;
};
class Student : public Person
{
public:
	virtual void BuyTicket() // 重写/覆盖 父类虚函数
	{
		cout << "正常排队-半价买票" << endl;
	}
protected:
	// ...
};
class Soldier : public Person
{
public:
	virtual void BuyTicket() // 重写/覆盖 父类虚函数
	{
		cout << "优先排队-全价买票" << endl;
	}
protected:
	// ...
};
void Func(Person* ptr)//或者引用,不能用对象
{
	// 多态 -- ptr指向父类对象调用父类的虚函数,指向子类对象调用子类虚函数
	ptr->BuyTicket();
}
int main()
{
	Person ps;
	Student st;
	Soldier sd;
	Func(&ps);
	Func(&st);
	Func(&sd);
	return 0;
}

在这里插入图片描述

虚函数

在这里插入图片描述

重写虚函数的两个例外

在这里插入图片描述

1、协变

// 虚函数重写中--协变
class A{};
class B : public A{};

class Person
{
public:
	virtual A* BuyTicket()
	{
		cout << "正常排队-全价买票" << endl;

		return new A;
	}
protected:
	int _age;
	string _name;
};

class Student : public Person
{
public:
	virtual B* BuyTicket()
	{
		cout << "正常排队-半价买票" << endl;

		return new B;
	}
protected:
	// ...
};

void Func(Person* ptr)
{
	// 多态 -- ptr指向父类对象调用父类的虚函数,指向子类对象调用子类虚函数
	ptr->BuyTicket();
}

int main()  
{
	Person ps;
	Student st;
	Func(&ps);
	Func(&st);
	return 0;
}

在这里插入图片描述
2、析构函数的重写
p1会调用父类的虚构函数
p2调用完子类的虚构函数还会调用父类的虚构函数
子类中的重写函数可以不加virtual函数但是建议加上

// 支持子类不加虚函数也构成重写的话
// 那么只要父类中析构函数是虚函数,析构函数就一定构成了重写
// 下面的问题就不存在了。
class Person {
public:
	virtual ~Person() { cout << "~Person()" << endl; }
};
class Student : public Person {
public:
	virtual ~Student() { cout << "~Student()" << endl; } // delete(str); 
};
int main()
{
	// 普通场景下面,虚函数是否重写都是ok的
	//Person p;
	//Student s;

	// new对象特殊场景--虚函数必须重写
	// 不是虚函数,person和student是隐藏关系
	// 是虚函数,person和student是重写关系
	Person* p1 = new Person;
	Person* p2 = new Student;
	delete p1; // -> p1->destructor() + operator delete(p1) 
	delete p2; // -> p2->destructor() + operator delete(p2) 
	return 0;
}

版权声明:本文为Ds19415169988原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。