C++多态
多态:同一操作作用于不同对象时,产生不同的行为,分为编译时多态和运行时多态
1.运行时多态(动态绑定)
1.虚函数
通过虚函数和基类指针/引用实现,具体调用那个函数在运行时决定。
class Shape {
public:
Shape() {}
virtual ~Shape() {}
virtual void draw() {
cout << "This is Shape::draw()" << endl;
}
};
class Circle : public Shape {
public:
Circle() {}
virtual ~Circle() {}
void draw() {
cout << "This is Circle::draw()" << endl;
}
};
Shape* shape = new Circle();
shape->draw(); //调用子类Circle的draw()函数
delete shape;
编译器为每个含虚函数的类生成一个虚函数表(vtable),存储函数指针,对象通过函数指针(vptr)访问。
2.纯虚函数与抽象类
纯虚函数(virtual void func() = 0;)强制基类必须实现同名的函数,此时基类变为抽象类,不能实例化。
class Shape {
public:
Shape() {}
virtual ~Shape() {}
virtual void draw() = 0;//纯虚函数
};
class Circle : public Shape {
public:
Circle() {}
virtual ~Circle() {}
void draw() {
cout << "This is Circle::draw()" << endl;
}
};
int main() {
//Shape* shape = new Shape();//编译不通过,报错invalid new-expression of abstract class type ‘Shape’
Shape* shape = new Circle();
shape->draw(); //调用子类Circle的draw()函数
delete shape;
return 0;
}
3.典型考题
- 求类大小
class Shape1 {
public:
Shape1() {}
~Shape1() {}
};
class Shape2 {
public:
Shape2() {}
virtual ~Shape2() {}
virtual void draw() = 0;
};
cout << sizeof(Shape1) << endl; //输出1
cout << sizeof(Shape2) << endl; //输出8,因为需要存虚函数表指针,所以大小为8(在32位机结果为4)
- 析构函数必须为虚函数
class Base {
public:
Base() {}
~Base() {}
virtual void PrintData() = 0;
};
class Derive : public Base {
public:
Derive(int data) : data(new int(data)) {}
~Derive()
{
cout << "Delete data." << endl;
delete data;
}
void PrintData() override
{
cout << "Data: " << *data << endl;
}
private:
int *data;
};
int main() {
Base* base = new Derive(2);
delete base;
return 0;
}
上述代码有什么错误?
- 当通过基类指针删除派生类对象时,若基类析构函数非虚函数,则派生类的析构函数不会被调用,导致内存泄漏。
2.编译多态
- 函数重载(Overload): 统一作用域内同名函数参数不同。
- 模板(Templaye):泛型编程,根据类型生成不同代码。
浙公网安备 33010602011771号