需要声明的,本节课件中的代码及解释都是在32平台(vs),涉及的指针都是4bytes。
如果要其他平台下,部分代码需要改动。比如:需要考虑指针是8bytes等问题。
class Sudent:public Person
{
public:
virtual void BuyTicket()
{
cout << "半票" << endl;
}
};
class Person
{
public:
virtual void BuyTicket()
{
cout << "全票" << endl;
}
};
class Sudent:public Person
{
public:
virtual void BuyTicket()
{
cout << "半票" << endl;
}
};
class Soldier :public Person
{
public:
virtual void BuyTicket()
{
cout << "优先买票" << endl;
}
};
void Fun(Person& p)
{
p.BuyTicket();
}
int main()
{
Person ps;
Sudent st;
Soldier sd;
}
注意:在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,也可以构成重写(因为继承后基类的虚函数被继承下来了在派生类依旧保持虚函数属性)。
void BuyTicket() { cout << "买票-半价" << endl; }
虚函数重写的两个例外:
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; }
};
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;
delete p1;
Person* p2 = new Student;
delete p2;
}
class Car
{
public:
virtual void Drive() final {}
};
class Benz :public Car
{
public:
virtual void Drive() { cout << "Benz-舒适" << endl; }
};
class Car {
public:
virtual void Drive() {}
};
class Benz :public Car {
public:
virtual void Drive() override { cout << "Benz-舒适" << endl; }
};
未重写会直接报错
在虚函数的后面写上 =0 ,则这个函数为纯虚函数。**包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象。**派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象。纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承。
class Car
{
public:
virtual void Drive() = 0;
};
class Benz :public Car
{
public:
virtual void Drive()
{
cout << "Benz-舒适" << endl;
}
};
class BMW :public Car
{
public:
virtual void Drive()
{
cout << "BMW-操控" << endl;
}
};
int main()
{
Car* bz = new Benz;
bz->Drive();
Car* bw = new BMW;
bw->Drive();
return 0;
}
多态条件满足: