联编就是将模块或者函数合并在一起生成可执行代码的处理过程,同时对每个模块或者函数调用分配内存地址,并且对外部访问也分配正确的内存地址,它是计算机程序彼此关联的过程。按照联编所进行的阶段不同,可分为两种不同的联编方法:静态联编和动态联编。
静态联编是指在编译阶段就将函数实现和函数调用关联起来,因此静态联编也叫早绑定,在编译阶段就必须了解所有的函数或模块执行所需要检测的信息,它对函数的选择是基于指向对象的指针(或者引用)的类型,C语言中,所有的联编都是静态联编,据我所知道的,任何一种编译器都支持静态联编(废话)。
动态联编是指在程序执行的时候才将函数实现和函数调用关联,因此也叫运行时绑定或者晚绑定,动态联编对函数的选择不是基于指针或者引用,而是基于对象类型,不同的对象类型将做出不同的编译结果。C++中一般情况下联编也是静态联编,但是一旦涉及到多态和虚拟函数就必须要使用动态联编了。
以上内容引用自
请看下面的程序:#includeusing namespace std; class A{public: A() { cout<<"new a A"<
test2函数执行后不会调用B类的析构函数。因为,A类和B类的析构函数都是静态联编的,即编译时就根据对象或指针的类型确定其在被销毁时将要调用的析构函数。则自然test2函数中唯一的变量pA在test2函数执行完后调用A类的析构函数,而在test2函数执行过程之中new出来的B类的一个对象,没有被销毁。这将导致内存泄露。那么怎样才能防止这类内存泄露,让test2执行完后也调用B类的析构函数呢?
这时候就需要用到动态联编了,也就是要用到虚函数。虚函数则是在程序运行时,根据其对象类型来调用相应的函数。请看下面的程序:#includeusing namespace std; class A{public: A() { cout<<"new a A"<
上面程序的输出结果是:
这说明,在test2执行后,delete pA时,是根据pA实际指向的对象来调用析构函数的,也就是调用B的析构函数。但是B是继承A的,故在调用B的析构函数后,会再去调用其父类即A类的析构函数。test1函数的执行过程充分说明了继承中构造函数和析构函数的调用顺序。这也恰好验证了test2函数中检验虚析构函数的功效。
使用虚析构函数,及时释放资源,防止内存泄露。但是在没有涉及到多态的时候可以不使用虚析构函数,毕竟任何虚函数都是要以类维护一个VTable和VTable指针为代价的。