c++虚析构函数的使用及其注意点】的更多相关文章

虚析构函数的作用主要是当通过基类指针删除派生类对象时,调用派生类的析构函数(如果没有将不会调用派生类析构函数) #include <iostream> using namespace std; class base { public: base() { cout << "base()" << endl; } virtual ~base() { cout << "~base()" << endl; } };…
7.为多态基类声明虚析构函数 1.为多态基类声明虚析构函数 code1: class A{ public: int* a; A():a(new int(5)) {} ~A(){ delete a; } }; class B:public A { public: int *b; B():b(new int(10)) {} ~B(){ delete b; } }; int main(int argc, char const *argv[]) { B *bb=new B; A* aa=bb; dele…
继承类研究 1. Code 1.1 Cbase, CTEST为基类,CTest2为其继承类,并重新申明了基类中的同名变量 class CBase { public: int Data; CBase(); ~CBase(); }; class CTEST { //Data: private: int PrivateData1; int PrivateData2; public: int Data; //Method: public: CTEST(); ~CTEST(); void PrintDat…
from:http://blog.csdn.net/fisher_jiang/article/details/2477577 一. 虚析构函数 我们知道,为了能够正确的调用对象的析构函数,一般要求具有层次结构的顶级类定义其析构函数为虚函数.因为在delete一个抽象类指针时候,必须要通过虚函数找到真正的析构函数. 如: class Base{public:   Base(){}   virtual ~Base(){}};class Derived: public Base{public:   D…
在C++中,构造函数用于在创建对象时进行初始化工作,不能声明为虚函数.因为在执行构造函数前对象尚未创建完成,虚函数表尚不存在,也没有指向虚函数表的指针,所以此时无法查询虚函数表,也就不知道要调用哪一个构造函数.下节会讲解虚函数表的概念. 析构函数则用于在销毁对象时完成相应的资源释放工作,可以被声明为虚函数. 为了说明虚析构函数的必要性,请大家先看下面一个例子: #include <iostream> using namespace std; //基类 class Base{ private:…
一.多态 多态性是面向对象程序设计的重要特征之一. 多态性是指发出同样的消息被不同类型的对象接收时有可能导致完全不同的行为. 多态的实现: 函数重载 运算符重载 模板 虚函数 (1).静态绑定与动态绑定 静态绑定 绑定过程出现在编译阶段,在编译期就已确定要调用的函数. 动态绑定 绑定过程工作在程序运行时执行,在程序运行时才确定将要调用的函数. 二.虚函数 虚函数的概念:在基类中冠以关键字 virtual 的成员函数 虚函数的定义: virtual 函数类型 函数名称(参数列表); 如果一个函数在…
一.纯虚函数 虚函数是实现多态性的前提 需要在基类中定义共同的接口 接口要定义为虚函数 如果基类的接口没办法实现怎么办? 如形状类Shape 解决方法 将这些接口定义为纯虚函数 在基类中不能给出有意义的虚函数定义,这时可以把它声明成纯虚函数,把它的定义留给派生类来做 定义纯虚函数: class 类名{         virtual 返回值类型 函数名(参数表) = 0:     }; 纯虚函数不需要实现 二.抽象类 作用 抽象类为抽象和设计的目的而声明,将有关的数据和行为组织在一个继承层次结构…
代码: #include <iostream> using namespace std; class A{ public: A(){ cout<<"construct A"<<endl; } virtual ~A(){ cout<<"destory A"<<endl; } }; class B:public A{ public: B(){ cout<<"construct B"…
知识背景 要弄明白这个问题,首先要了解下C++中的动态绑定. 关于动态绑定的讲解,请参阅:  C++中的动态类型与动态绑定.虚函数.多态实现 正题 直接的讲,C++中基类采用virtual虚析构函数是为了防止内存泄漏.具体地说,如果派生类中申请了内存空间,并在其析构函数中对这些内存空间进行释放.假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数.那么在这种情况下,派生类中申请的空间就得不到释放从而产生内存泄漏…
c++  虚析构函数: 虚析构函数(1)虚析构函数即:定义声明析构函数前加virtual 修饰, 如果将基类的析构函数声明为虚析构函数时,由该基类所派生的所有派生类的析构函数也都自动成为虚析构函数. (2)基类指针pbase 指向用new动态创建的派生类对象child时,用“delete pbase;”删除对象分两种情况:第一,如果基类中的析构函数为虚析构函数,则会先删除派生类对象,再删除基类对象第二,如果基类中的析构函数为非虚析构函数,则只会删除基类对象,不会删除派生类对象,这样便出现了内存泄…
构造函数和析构函数的调用顺序 构造函数的调用顺序: 当建立一个对象时,首先调用基类的构造函数,然后调用下一个派生类的构造函数,依次类推,直至到达最底层的目标派生类的构造函数为止. 析构函数的调用书序: 当删除一个对象时,首先调用该派生类的析构函数,然后调用上一层基类的析构函数,依次类推,直到到达最顶层的基类的析构函数为止. 简单的说,构造函数是"自上向下"调用,析构函数是"自下而上"调用. 演示代码如下: #include<iostream> using…
1. 继承体系中关于对象释放遇到的问题描述 1.1 手动释放 关于时间记录有很多种方法,因此为不同的计时方法创建一个TimeKeeper基类和一些派生类就再合理不过了: class TimeKeeper { public: TimeKeeper(); ~TimeKeeper(); ... }; class AtomicClock: public TimeKeeper { ... }; class WaterClock: public TimeKeeper { ... }; class Wrist…
一:纯虚函数和抽象类 纯虚函数是一个在基类中说明的虚函数,在基类中没有定义,要求任何派生类都定义自己的版本 纯虚函数为各个派生类提供一个公共接口 纯虚函数的形式: virtual 类型 函数名(参数列表)=0: 一个具有纯虚函数的基类称为抽象类 注意:抽象类不能实例化对象 一个派生类继承抽象类但是未实现纯虚函数,则也变为抽象类,可以继续被继承实现 class Parent //抽象类 { public: Parent() { cout << "Parent construct&quo…
学习资料 • C++中基类的析构函数为什么要用virtual虚析构函数 虚析构函数 1. 正文 直接的讲,C++中基类采用virtual虚析构函数是为了防止内存泄漏.具体地说,如果派生类中申请了内存空间,并在其析构函数中对这些内存空间进行释放.假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数.那么在这种情况下,派生类中申请的空间就得不到释放从而产生内存泄漏.所以,为了防止这种情况的发生,C++中基类的析构函…
参考:http://www.weixueyuan.net/view/6373.html 总结: 构造函数是不能声明为虚函数的,析构函数可以被声明为虚函数. 将基类的析构函数声明为虚函数之后,派生类的析构函数也自动成为虚析构函数. 未将基类的析构函数定义为虚函数,如下面的例子的情况可能会出现内存泄漏.原因是不构成多态,函数属于编译期绑定,无论基类指针p指向的是派生类对象或者是基类对象,执行的都将会是基类的函数. 通常来说,如果基类中存在一个指向动态分配内存的成员变量,并且基类的析构函数中定义了释放…
//############################################################################ /* 在多态虚基类中声明一个虚析构函数 */ /* 为什么需要虚析构函数 */ class yellowdog : public dog { }; dog* dogFactory::createDog() { dog* pd = new yellowdog(); return pd; } int main() { dog* pd = dog…
虚函数作用:动态绑定,实现多态效果. 场景问题: 派生类中有资源需要回收,而在编程中采用多态,由基类的指针指向派生类,则在释放的时候,如果基类的析构函数不是virtual,则派生类的析构函数得不到释放 总结: C++中基类采用virtual虚析构函数是为了防止内存泄漏.具体地说,如果派生类中申请了内存空间,并在其析构函数中对这些内存空间进行释放.假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数.那么在这种情…
当派生类对象从内存中撤销时一般先运行派生类的析构函数,然后再调用基类的析构函数. 如果用new运算符建立的派生类的临时对象,对指向基类的指针指向这个临时对象当用delete运算符撤销对象时,系统执行的是基类的析构函数,而不是派生类的析构函数,不能彻底的“清理现场”.解决的方法是将基类及派生类的析构函数设为虚函数,这时无论基类指针指向哪个派生类对象,系统会采用动态关联,调用相应的析构函数对对象进行清理.   class Point { public :           Point(){};  …
; 这就是一个纯虚析构函数,这种定义是允许的. 一般纯虚函数都不允许有实体,但是因为析构一个类的过程中会把所有的父类全析构了,所以每个类必有一个析构函数. 所以.纯虚析构函数需要提供函数的实现,而一般纯虚函数不能有实现…
虚析构函数的理论前提是 执行完子类的析构函数,那么父类的虚构函数必然会被执行. 那么当用delete释放一个父类指针所实例化的子类对象时,如果没有定义虚析构函数,那么将只会调用父类的析构函数,而不会调用子类的虚构函数,导致内存的泄漏. 故: 继承时,要养成的一个好习惯就是,基类析构函数中,加上virtual. 知识背景 要弄明白这个问题,首先要了解下C++中的动态绑定. 关于动态绑定的讲解,请参阅:  C++中的动态类型与动态绑定.虚函数.多态实现 正题 直接的讲,C++中基类采用virtual…
1.静态联编和动态联编联编:将源代码中的函数调用解释为要执行函数代码. 静态联编:编译时能确定唯一函数.在C中,每个函数名都能确定唯一的函数代码.在C++中,因为有函数重载,编译器须根据函数名,参数才能确定唯一的函数代码. 动态联编:编译时不能确定调用的函数代码,运行时才能.C++中因为多态的存在,有时编译器不知道用户将选择哪种类型的对象,因此无法确定调用的唯一性,只有在运行时才能确定. 2.虚成员函数,指针或引用,动态联编指针或引用才能展现类的多态性.当类中的方法声明为virtual时,使用指…
先看代码: #include<iostream> using namespace std; class Parent { public: Parent() :a(), b(), c() { p = ]; //strcpy(p, "abc"); cout << "parent 无参构造...\n"; } Parent(), b(), c() { p = ]; //strcpy(p, "abc"); cout <<…
1.构造函数 C++中的构造函数是用于初始化类的各种变量以及分配资源等.主要的注意事项是: (1)在继承关系中先初始化父类对象后初始化子类对象. (2)在一个类中按照变量的声明顺序,对类中的变量进行初始化. (3)初始化过程中,可以使用已经被初始化的对象去初始化其他的对象. 2.析构函数 析构函数与构造函数作用相反,当对象脱离其作用域时(例如对象所在的函数已调用完毕),系统自动执行析构函数. 析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数…
五条基本规则: 1.如果基类已经插入了vptr, 则派生类将继承和重用该vptr.vptr(一般在对象内存模型的顶部)必须随着对象类型的变化而不断地改变它的指向,以保证其值和当前对象的实际类型是一致的. 2.在遇到通过基类指针或引用调用虚函数的语句时,首先根据指针或引用的静态类型来判断所调函数是否属于该class或者它的某个public 基类,如果 属于再进行调用语句的改写:  C++ Code  1   (*(p->_vptr[slotNum]))(p, arg-list); 其中p是基类指针…
C++ 虚析构函数 20131010 在C++中的虚函数作用是实现基于继承机制的多态,但是我们好像忽略了一种情况,就是虚析构函数.在C++继承机制中,虽然构造函数是不可以使用虚函数声明,但是析构函数是可以声明为虚函数的.这样做的目的是为了当父类指针指向一个派生类的对象的时候,当删除该指针的时候,可以调用派生类的析构函数,释放资源.如果不是这样的话,那么在C++中的派生类的内存空间是不会被释放掉,会造成内存的浪费,最终导致内存溢出而是程序崩溃. 但是我们不能够随意的使用虚函数声明,因为会增加类的存…
Without Virtual Destructor(虚析构函数) class A{ public: ; A() { cout <<"A()..."<< endl; } ~A() { cout << "~A()..." << endl; } }; class B : public A{ public: int b; B(){ cout << "B()..." << endl;…
//虚析构函数的重要性 #include<iostream> using namespace std; /* 虚析构函数 主要用在多态中,用来释放子类对象内存空间,如果不使用虚析构函数, 那么在多态的场景下,使用delete关键字只能执行父类析构函数 子类对象中没有父类对象 父类中有虚函数,子类中重写了该虚函数,那么默认子类中重写的函数也是虚函数,子类中不写virtual关键字也可以 但是为了代码的可读性,还是在子类中也加上virtual 关键字 */ class Point{ public:…
什么样的情况下才需要虚析构函数? 类需要控制自己的对象执行一系列操作时发生什么样的行为,这些操作包括:创建(对象).拷贝.移动.赋值和销毁.在继承体系中,如果一个类(基类或其派生的类)没有定义拷贝控制操作,则编译器将自动的为其合成一个.即为合成的拷贝控制. 在基类的拷贝控制中,由于继承关系导致的最大影响就是:基类通常应该定义一个‘虚析构函数’.用以动态的分配继承体系中的对象. 如:类A,B,C,D有如下继承关系(代码1): 1 2 3 4 class A; class B:public A; c…
1.虚函数 原因:通过指针调用成员函数时,只能访问到基类的同名成员函数.在同名覆盖现象中,通过某个类的对象(指针及引用)调用同名函数,编译器会将该调用静态联编到该类的同名函数,也就是说,通过基类对象指针是无法访问派生类的同名函数的,即使这个指针是用派生类对象来初始化的. 虚函数是C++中用于实现多态(polymorphism)的机制.核心理念就是通过基类访问派生类定义的函数. 指向基类的指针在操作它的多态类对象时,会根据不同的类对象,调用其相应的函数,这个函数就是虚函数. 可以说,基类声明的虚函…
1.若某种语言只支持类但不支持多态,则只能称为基于对象,不能说是面向对象. 2.多态:向不同对象发送同一个消息,不同的对象会产生不同的行为,发送消息可以是调用函数等操作.函数重载.运算符重载都是多态. 3.多态分为静态和动态: 静态多态性:函数重载和运算符重载(实质也是函数重载),编译时就知道调用哪个函数: 动态多态性:编译时不知道调用哪个函数,运行时才知道,是要通过虚函数实现的. 4.虚函数:当父类指针指向子类时,只能调用子类中的父类部分,但是如果父类中的某个成员函数被声明为虚函数时,该指针就…