C++多态
C++多态的应用主要有以下几个方面:
-
虚函数和动态绑定:通过在基类中声明虚函数,并在派生类中进行重写,可以实现动态绑定。这样,通过基类指针或引用调用虚函数时,会根据实际对象的类型来决定调用哪个函数。这种机制使得在运行时能够根据对象的实际类型来调用相应的函数,实现多态性。
-
抽象类和接口:通过将基类中的某些函数声明为纯虚函数,从而创建抽象类。抽象类不能被实例化,只能被用作其他类的基类。派生类需要实现纯虚函数才能被实例化,从而实现接口的定义和强制。
-
多态数组和容器:C++的容器类(如vector、list、map等)可以存储基类指针或引用,从而可以存储不同派生类的对象。通过使用多态,可以实现对不同派生类对象的统一管理和操作。
-
虚析构函数:当基类指针指向派生类对象时,如果基类中的析构函数不是虚函数,只会调用基类的析构函数,而不会调用派生类的析构函数。这会导致派生类中的资源无法正确释放。通过将基类的析构函数声明为虚函数,可以确保在删除派生类对象时,会先调用派生类的析构函数,再调用基类的析构函数。
总的来说,C++多态的应用可以提高代码的灵活性和可扩展性,使得程序能够更好地适应不同的需求和变化。
虚函数
#include <iostream>
using namespace std;
class A
{
public:
A() {}
virtual ~A() { cout << "A~~~~~~~~~" << endl; }//虚函数
virtual void show()
{
cout << "AAAAAAAAAAAAA" << endl;
}
};
class AX :public A
{
public:
~AX() { cout << "AX~~~~~~~~~" << endl; }
void show()
{
cout << "BBBBBBBBBBBBB" << endl;
}
};
int main()
{
// AX a;
// AX *p = new AX;
// delete p;
A* p = new AX;
delete p;
/*
A a;
a.show();
AX b;
b.show();
*/
#if 0
AX a;
AX* q = &a;
A* p = &a;//支持基类的指针指向派生类的地址
q->show();
p->show();
#endif
}
虚函数( 基类指针可指向派生类对象, 动态联编)
设计一个函数能求多个“图形”总周长?
#include <iostream>
using namespace std;
class shape
{
public:
virtual double getC(void) = 0;//声明为纯虚函数
// {
// }
};
class Cir :public shape
{
public:
Cir(double ri) :r(ri) {}
double getC(void)
{
return 2 * 3.14 * r;
}
private:
int r;
};
class Tri :public shape
{
public:
Tri(double a, double b, double c) :e1(a), e2(b), e3(c) {}
double getC(void)
{
return e1 + e2 + e3;
}
private:
double e1;
double e2;
double e3;
};
class Rec : public shape
{
public:
Rec(double e)
{
this->e = e;
}
double getC(void)
{
return 4 * e;
}
private:
double e;
};
double countC(shape* arr[], int n)
{
double sum = 0;
for (int i = 0; i < n; i++)
{
sum += arr[i]->getC();
}
return sum;
}
int main()
{
shape x;
Cir c(1);
Rec r(3);
Cir c1(2);
Tri t(3, 3, 3);
shape* arr[] = { &c, &r, &c1, &t };
cout << "total C: " << countC(arr, 4) << endl;
}
纯虚函数,纯虚类
形式:
virtual void func() = 0;
目的:
a. 统一接口
b. 强制实现
虚析构函数(内存泄漏)
基类指针释放派生类对象
class A{
~A(){
cout<<“~~~~~A”;
}
};
Class B:public A{
~B(){
cout<<“~~~~~~B”;
}
};
code:
A *p = new B;
delete p; //????
#include <iostream>
using namespace std;
class A
{
public:
A() {}
virtual ~A() { cout << "A~~~~~~~~~" << endl; }//虚析构函数
virtual void show()//虚函数
{
cout << "AAAAAAAAAAAAA" << endl;
}
};
class AX :public A
{
public:
~AX() { cout << "AX~~~~~~~~~" << endl; }
void show()
{
cout << "BBBBBBBBBBBBB" << endl;
}
};
int main()
{
// AX a;
// AX *p = new AX;
// delete p;
A* p = new AX;
delete p;
/*
A a;
a.show();
AX b;
b.show();
*/
#if 0
AX a;
AX* q = &a;
A* p = &a;//支持基类的指针指向派生类的地址
q->show();
p->show();
#endif
}