多态的概念
通俗来说就是多种形态,具体就是去完成某个行为,当不同的对象去完成时会产生出不同的状态
多态两个条件:
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版权协议,转载请附上原文出处链接和本声明。