C++ 多态

多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了
Person。Person对象买票全价,Student对象买票半价


class Person {
public:
	virtual void BuyTicket() { cout << "买票-全价" << endl; }
};
class Student : public Person {
public:
	virtual void BuyTicket() { cout << "买票-半价" << endl; }
	/*注意:在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,虽然也可以构成重写(因
	为继承后基类的虚函数被继承下来了在派生类依旧保持虚函数属性),但是该种写法不是很规范,不建议
	这样使用*/
	/*void BuyTicket() { cout << "买票-半价" << endl; }*/
};
void Func(Person& p)

//虚函数重写的两个例外:
//1. 协变(基类与派生类虚函数返回值类型不同)
//派生类重写基类虚函数时,与基类虚函数返回值类型不同。即基类虚函数返回基类对象的指
//针或者引用,派生类虚函数返回派生类对象的指针或者引用时,称为协变。(了解)
//2. 析构函数的重写(基类与派生类析构函数的名字不同)
//如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,
//都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同。虽然函数名不相同,
//看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处
//理,编译后析构函数的名称统一处理成destructor。
{
	p.BuyTicket();
}
int main()
{
	Person ps;
	Student st;
	Func(ps);
	Func(st);
	return 0;
}

 原理图

C++ 多态_第1张图片 多态条件C++ 多态_第2张图片

 举例(ps:下面就是通过修改多态的条件从而不满足多态)

void Func(Person p)
{
	p.BuyTicket();
}

 

要求三同,假设我们这里让参数不同:


class Person {
public:
	virtual void BuyTicket() { cout << "买票-全价" << endl; }
};
class Student : public Person {
public:
	virtual void BuyTicket(int ) { cout << "买票-半价" << endl; }

};

 

重写虚函数

Person* p=new Person;
	delete p;
	p = new Student;
	delete p;

我们发现子类的析构函数没有被正确调用。

这是因为delete是根据指针类型来调用的。

但是person指针可能指向person,也可能指向student。

它的调用如下:先调用destrutor函数再调用析构函数。 destrutor是普通函数,普通函数调用看类型,因为是person指针类型,所以调用person析构。

我们不希望它是普通继承,因为如果是普通继承就不会调子类析构,会造成内存泄漏。

C++ 多态_第3张图片

那我们怎么样让它变多态呢?第一:三同(参数相同,函数名相同,返回值相同)

二:虚函数重写

~Person()    ~Student()参数没有,返回值没有,函数名不同,但是为了满足多态进行了特殊处理。

现在只差虚函数重写这一项了,我们给析构加上virtual:

virtual ~Person()
	{
		cout << "~Person()" << endl;
	}
};

virtual ~Student()
	{
		cout << "~Student()" << endl;
	}

你可能感兴趣的:(c++,开发语言)