多态的概念
多态的概念:通俗来说,就是多种形态,具体点就是去完成某种行为,不同的对象去完成时会长生不同的状态。
比如:买车票就是一种多态行为,不同的人去买票价格可能不一样,就像成人票和学生票的价格就会有差异 ,但是买票是同一种行为,不同的人买就会产生不同的状态或者结果,这就叫做多态!
一、构成多态的条件
1、重写
1.1、虚函数:即被virtual修饰的类成员函数称为虚函数
class Person
{
public:
virtual void BuyTicket()
{
cout << "成人票—> 全价" << endl;
}
};
1.2、虚函数的重写(覆盖)
派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名、参数列表完全相同),
称子类的虚函数重写了基类的虚函数。
class Person
{
public:
virtual void BuyTicket()
{
cout << "成人票—> 全价" << endl;
}
};
class Student :public Person
{
public:
virtual void BuyTicket()
{
cout << "学生票—>打八折" << endl;
}
};
2、必须是父类的指针或者引用调用虚函数
class Person
{
public:
virtual void BuyTicket()
{
cout << "成人票—> 全价" << endl;
}
};
class Student :public Person
{
public:
virtual void BuyTicket()
{
cout << "学生票—>打八折" << endl;
}
};
void Func(Person& p)//父类的引用
{
p.BuyTicket();
}
int main()
{
Person adult;
Student collegestudent;
Func(adult);
Func(collegestudent);
return 0;
}
二、重写
1.构成重写两个的条件
1.1、必须是虚函数
1.2、派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名、参数列表完全相同)
1.3、析构函数的重写(基类与派生类的函数名字不相同)
class Person {
public:
virtual ~Person() { cout << "~Person()" << endl; }
};
class Student : public Person {
public:
virtual ~Student() { cout << "~Student()" << endl; }
};
// 只有派生类Student的析构函数重写了Person的析构函数,下面的delete对象调用析构函
//数,才能构成多态,才能保证p1和p2指向的对象正确的调用析构函数。
int main()
{
Person* p1 = new Person;
Person* p2 = new Student;
delete p1;
delete p2;
return 0;
}
2.重写的两个特例
2.1、子类函数不加virtual也依旧构成重写
原因是继承后基类的虚函数被继承下来了在派生类依旧保持虚函数属性,但是在实际应用中虚函数最好加virtual修饰,避免混淆。
class Person
{
public:
virtual void BuyTicket()
{
cout << "成人票—>全价" << endl;
}
};
class Student :public Person
{
public:
//1、子类虚函数不加virtual,依旧构成重写(但是在实际中通常都加virtual)
void BuyTicket()
{
cout << "学生票—>半价" << endl;
}
};
2.2、重写协变
class A{};
class B : public A {};
class Person {
public:
virtual A* f() {return new A;}
};
class Student : public Person {
public:
virtual B* f() {return new B;}
};
三、多态原理
1.虚函数表
2.多态调用

class Person {
public:
virtual void BuyTicket() { cout << "买票-全价" << endl; }
};
class Student : public Person {
public:
virtual void BuyTicket() { cout << "买票-半价" << endl; }
};
void Func(Person& p)
{
p.BuyTicket();
}
int main()
{
Person Mike;
Func(Mike);
Student Johnson;
Func(Johnson);
return 0;
}
总结
多态的特性(构成多态的条件)
1.必须构成重写
重载、覆盖(重写)、隐藏(重定义)的对比

2.必须是父类的指针或者引用去调用虚函数
多态的本质原理就是符合两个多态的条件,调用时会到对象的虚表中找到对应的虚函数地址,进行调用,如果不是父类的指针或者引用去调用虚函数,那么此时就是普通函数的调用就不会产生多态的行为或者状态
注意:
多态调用是指程序运行时去指向的对象的虚表中找到函数地址,而普通函数的调用是在编译链接时就确定了函数的地址,运行时直接调用。
337

被折叠的 条评论
为什么被折叠?



