行业网站方案,知名品牌网站有哪些,新网站做seo优化步骤,海珠区 网站设计虽然我们已经知道了什么是继承和多态#xff0c;也明白了多态依赖于继承#xff0c;但是在多态中存在哪些问题呢#xff1f; 多态中可能存在的内存泄露问题 例如下面的程序中#xff0c;在圆形Circle的类中定义一个圆心的坐标#xff0c;并且坐标是在堆中申请的内存#…虽然我们已经知道了什么是继承和多态也明白了多态依赖于继承但是在多态中存在哪些问题呢 多态中可能存在的内存泄露问题 例如下面的程序中在圆形Circle的类中定义一个圆心的坐标并且坐标是在堆中申请的内存则在mian函数中通过基类指针操作派生类对象的成员函数是没有问题的可是在销毁对象内存的时候则只是执行了基类的析构函数派生类的析构函数却没有执行这会导致内存泄漏。换句话说如果delete后边跟基类的指针则只会执行基类的析构函数如果delete后面跟的是派生类的指针那么它即会执行派生类的析构函数也会执行基类的析构函数 class Shape
{
public:virtual double calcArea(){...}//虚函数Shape();~Shape();....
private:....
};
Shape::Shape()
{
coutclass Shape was createdendl;
}
Shape::~Shape()
{
coutclass Shape was deletedendl;
}
class Circle:public Shape
{
public:Circle(int x,int y,double r);~Circle();virtual double calcArea();//此处可不加virtual但系统默认加上....
private:double m_dR;Coordinate *m_pCenter; //坐标类指针....
};
Circle::Circle(int x,int y,double r)
{m_pCenternew Coordinate(x,y);m_dRr;coutclass Circle was createdendl;
}
Circle::~Circle()
{delete m_pCenter;m_pCenterNULL;coutclass Circle was deletedendl;
}
....
int main()
{Shape *shape1new Circle(5,6,4.0);//基类对象改成Circle *circlenew Circle(5,6,4.0)则为派生类对象shape1-calcArea();delete shape1;shape1NULL;//派生类对象的内存未回收return 0;
} 打印结果可见派生类的析构函数并没有被执行而只是回收了开辟给基类对象的空间那如何解决这个问题呢固然可以通过delete派生类对象实现除此之外还可以引入虚析构函数你看普通的虚函数都可以实现多态的动态联编那对于析构函数呢虚析构函数也会在最后对象销毁内存时动态链接到派生类对象。 可以这样解释它如果基类当中定义了虚析构函数那么基类的虚函数表当中就会有一个基类的虚析构函数的入口指针指向的是基类的虚析构函数派生类的虚函数表当中也会产生一个派生类的虚析构函数的入口指针指向的是派生类的虚析构函数这个时候使用基类的指针指向派生类的对象delete掉基类指针就会通过指向的基类的对象找到基类的虚函数表指针从而找到虚函数表在虚函数表中找到派生类的虚析构函数从而使得派生类的析构函数得以执行派生类的析构函数执行之后系统会自动执行父类的虚析构函数。即整个执行过程是 基类的构造函数派生类的构造函数......派生类的析构函数基类的析构函数。 virtual关键字可以修饰普通的成员函数也可以修饰析构函数但并不是没有限制 virtual在函数中的使用限制 普通函数不能是虚函数也就是说这个函数必须是某一个类的成员函数不可以是一个全局函数否则会导致编译错误。静态成员函数不能是虚函数 static成员函数是和类同生共处的他不属于任何对象使用virtual也将导致错误。内联函数不能是虚函数 如果修饰内联函数 如果内联函数被virtual修饰计算机会忽略inline使它变成存粹的虚函数。inline将会在后面的博客中介绍构造函数不能是虚函数否则会出现编译错误。转载于:https://www.cnblogs.com/cvtoEyes/p/8492247.html