多态调用条件:
1 .必须通过基类的指针或者引用调用虚函数
2 .被调用的函数必须是虚函数,且派生类必须以基类的虚函数进行重写
不符合就是普通调用
class Person
{
public:
virtual B* f()
{
cout << "Person::f()" << endl;
return new B;
}
};
class Student
{
public:
virtual B* f()
{
cout << "Student::f()" << endl;
return new B;
}
};
int main()
{
Person p;
Student s;
Person* ptr = &p;
ptr->f();
ptr=&s;
ptr->f();
}
析构函数能不能定义成虚函数
可以
是否必须定义成虚函数
特定条件下如下:
class Person
{
public:
virtual ~Person()
{
cout <<"~Person()" << endl;
}
};
class Student::public Person
{
public:
virtual ~Student()
{
cout << "~Student()" << endl;
}
};
int main()
{
Person p;
Student s;
return 0;
}
int main()
{
必须定义成虚函数
//Person* p1=new Person;
//delete p1;
Person* p2=new Student;
delete p2;
}
重写、重载、重定义对比
重写: 两个函数在同一作用域,函数名相同,参数相同。
重载: 两个函数分别在基类和派生类的作用域,函数名,参数,返回值都相同(协变除外),两个函数必须是虚函数。
重定义: 两个函数必须在基类和派生类的作用域,函数名相同,两个同名函数不构成重写就是重定义。
抽象类
不能实例化对象
包含纯虚函数
class Car//抽象类、接口类
{
public:
virtual void Drive() = 0;//纯虚函数
};
class BMW : public Car(接口继承)
{
virtual void Drive()
{
cout << "操控" << endl;(强制进行重写)
}
};
int main()
{
//Car c;
BMW b;
}
多态原理
class Base
{
public:
virtual void Func1()
{
cout << "Func1()" << endl;
}
private:
char _c;
int _b=1;
};
//虚函数存在代码段
//虚函数的地址存在于对象的虚函数表里面
class Drive : public Base
{
public:
virtual void Func1()
{
cout << "Drive::Func1()" << endl;
}
private:
int _d = 2;
};
int main()
{
//虚函数表指针:指向函数指针数组
cout << sizeof(Base) << endl;
Base b;//12
Drive d;//16
cout << sizeof(Drive) << endl;
Base* ptr = &b;
ptr->func1();
ptr = &d;
ptr->func1();
return 0;
}
虚函数表:
存放虚函数的地址
对象存放虚函数表的地址
vs下:存在于代码段
Linux:存在于