避免在C#中使用析构函数Finalizer】的更多相关文章

博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:避免在C#中使用析构函数Finalizer.…
C++中的析构函数 简介 析构函数(Destructors),是对象的成员函数,没有返回值也没有参数,且一个类只有一个析构函数,当对象被销毁的时候调用,被销毁通常有这么几个情况. 函数执行结束 程序执行结束 程序块包含的局部变量 delete操作 什么时候要自己写析构函数? 编译器会自动创建默认的析构函数,通常都没有问题,但是当我们在类中动态分配了内存空间时,我们需要手段的回收这块空间,防止内存溢出.就像这样 class String { private: char *s; int size;…
我们知道,用C++开发的时候,用来做基类的类的析构函数一般都是虚函数.可是,为什么要这样做呢?下面用一个小例子来说明:         有下面的两个类: class ClxBase { public: ClxBase() {}; virtual ~ClxBase() {}; virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; }; }; class ClxD…
我们知道,用C++开发的时候,用来做基类的类的析构函数一般都是虚函数.可是,为什么要这样做呢?下面用一个小例子来说明:        有下面的两个类: class ClxBase{public:    ClxBase() {};    virtual ~ClxBase() {}; virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; };}; class Cl…
NET中的资源分托管和非托管,所谓的托管是指CLR(通用语言运行时)中进行管理的资源,它可以由CLR自动进行内存回收. 也就是大家熟知的GC(垃圾回收机制). 而对于 非托管资源,比如数据库连接,COM连接等,那么需要手动清理回收资源. 清理非托管资源,我们可以用析构函数来执行,虽然它的执行时机不确定,但终究会被执行. 当然还有Dispose()和Close()方法,两者的区别在于,Close()后还要以用Open()打开,而Dispose()则是彻底销毁.--- 使用析构函数时,需要GC.Co…
#include <iostream> using namespace std; class Father { public: ~Father() { cout << "Father's Desconstruct Called. " << endl; } }; class Son: public Father { public: ~Son() { cout << "Son's Desconstruct Called "…
当指向基类的指针指向新建立的派生类对象而且基类和派生类都调用new向堆申请空间时,必须将基类的析构函数声明为虚函数,从而派生类的析构函数也为虚函数,这样才能在程序结束时自动调用它,从而将派生类对象申请的空间归还给堆. 附上一段代码诠释上述概念: #include <iostream> #include <string> using namespace std; class base{ char *p; public: base(int sz,char *bptr){ p=new c…
转自:http://blog.csdn.net/starlee/article/details/619827 我们知道,用C++开发的时候,用来做基类的类的析构函数一般都是虚函数.可是,为什么要这样做呢?下面用一个小例子来说明:        有下面的两个类: class ClxBase { public: ClxBase() {}; virtual ~ClxBase() {}; virtual void DoSomething() { cout << "Do something i…
<?php namespace app\api\controller; use think\Controller; class User extends Controller { public $data = [ 'code' => 0, ]; public function register() { // To do something } public function login() { // To do something } } 用ThinkPHP编写API服务的时候,一般都是直接R…
代码: #include <cstdio> #include <iostream> using namespace std; class A{ public: ~A(){ cout<<"~A()"<<endl; } }; class B:public A{ public: ~B(){ cout<<"~B()"<<endl; } }; int main(){ A* pA = new B(); de…
释放类所使用的未托管资源的两种方式:  1.利用运行库强制执行的析构函数,但析构函数的执行是不确定的,而且,由于垃圾收集器的工作方式,它会给运行库增加不可接受的系统开销. 2.IDisposable接口提供了一种机制,允许类的用户控制释放资源的时间,但需要确保执行Dispose(). 一般情况下,最好的方法是执行这两种机制,获得这两种机制的优点,克服其缺点.假定大多数程序员都能正确调用Dispose(),实现IDisposable接口,同时把析构函数作为一种安全的机制,以防没有调用Dispose…
如果构造函数打开了一个文件,最后不需要使用时文件就要被关闭.析构函数允许类自动完成类似清理工作,不必调用其他成员函数.析构函数也是特殊的类成员函数.简单来说,析构函数与构造函数的作用正好相反,它用来完成对象被删除前的一些清理工作,也就是专门的扫尾工作. 详细的时说: 自动调用基类部分的析构函数对基类的设计有重要影响.删除指向动态分配对象的指针时,需要运行析构函数在释放对象的内存之前清除对象.处理继承层次中的对象时,指针的静态类型可能与被删除对象的动态类型不同,可能会删除实际指向派生类对象的基类类…
我们知道,在c++中,析构函数是在函数作用域尾部执行析构函数,从而释放对象,但是有一种情况下,析构函数作用域发生变化,请看下面的例子,定义了一个Stock类,Stock类存放在stock.h中,主调用函数在stock.cpp中. stock.h #include <iostream> #include <string.h> class Stock{ private: ]; int m_stock_num; float m_stock_price; float total_price…
知识背景 要弄明白这个问题,首先要了解下C++中的动态绑定. 关于动态绑定的讲解,请参阅:  C++中的动态类型与动态绑定.虚函数.多态实现 正题 直接的讲,C++中基类采用virtual虚析构函数是为了防止内存泄漏.具体地说,如果派生类中申请了内存空间,并在其析构函数中对这些内存空间进行释放.假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数.那么在这种情况下,派生类中申请的空间就得不到释放从而产生内存泄漏…
转自:http://www.blogjava.net/fhtdy2004/archive/2009/05/30/278971.html 很多情况下要求当前的程序中只有一个object.例如一个程序只有一个和数据库的连接,只有一个鼠标的object.通常我们都将构造函数的声明置于public区段,假如我们将其放入private区段中会发生什么样的后果?这意味着什么? (1)构造函数定义private      当我们在程序中声明一个对象时,编译器为调用构造函数(如果有的话),而这个调用将通常是外部…
//############################################################################ /* * 不要让异常离开析构函数 * 析构函数中抛异常,会导致可能同时有多个异常pending * 因为一旦出现异常,栈回退的过程中会析构函数.如果析构函数又抛出异常,就会有多个异常pending */ class dog { public: string m_name; dog(string name) {m_name = name; c…
虚析构函数的理论前提是 执行完子类的析构函数,那么父类的虚构函数必然会被执行. 那么当用delete释放一个父类指针所实例化的子类对象时,如果没有定义虚析构函数,那么将只会调用父类的析构函数,而不会调用子类的虚构函数,导致内存的泄漏. 故: 继承时,要养成的一个好习惯就是,基类析构函数中,加上virtual. 知识背景 要弄明白这个问题,首先要了解下C++中的动态绑定. 关于动态绑定的讲解,请参阅:  C++中的动态类型与动态绑定.虚函数.多态实现 正题 直接的讲,C++中基类采用virtual…
C# 中的构造函数 类的 构造函数 是类的一个特殊的成员函数,当创建类的新对象时执行. 构造函数的名称与类的名称完全相同,它没有任何返回类型. 下面的实例说明了构造函数的概念: using System; namespace LineApplication { class Line { private double length; // 线条的长度 public Line() { Console.WriteLine("对象已创建"); } public void setLength(…
1,new 关键字和 malloc 函数区别(自己.功能.应用): 1,new 关键字是 C++ 的一部分: 1,如果是 C++ 编译器,则肯定可以用 new 申请堆空间内存: 2,malloc 是由 C 库提供的函数: 1,如果没有相应的库,malloc 将不能使用: 2,有些特殊的嵌入式开发中,少了 C 库,则就不能动态内存分配: 3,new 以具体类型为单位进行内存分配: 1,面向对象中一般用 new,不用 malloc: 4,malloc 以字节为单位进行内存分配: 5,new 在申请内…
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时间,但随着Java 6,7,8,甚至9的发布,Java语言发生了深刻的变化. 在这里第一时间翻译成中文版.供大家学习分享之用. 8. 避免使用Finalizer和Cleaner机制 Finalizer机制是不可预知的,往往是危险的,而且通常是不必要的. 它们的使用会导致不稳定的行为,糟糕的性能和移植…
原文地址:http://www.csharpwin.com/csharpspace/8927r1397.shtml MSDN建议按照下面的模式实现IDisposable接口: public class Foo: IDisposable { public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!m_dispos…
来自<CLR via C# 3rd Edition>总结 只管理内存,非托管资源,如文件句柄,GDI资源,数据库连接等还需要用户去管理 循环引用,网状结构等的实现会变得简单.GC的标志也压缩算法能有效的检测这些关系,并将不再被引用的网状结构整体删除. GC通过从程序的根对象开始遍历来检测一个对象是否可被其他对象访问,而不是用类似于COM中的引用计数方法. GC在一个独立的线程中运行来删除不再被引用的内存 GC每次运行时会压缩托管堆 你必须对非托管资源的释放负责.可以通过在类型中定义Finali…
Finalizer和Cleaner并不等同于C++中的析构函数,是不确定多久会被调用的,甚至有时候可能不会被调用,因此除了作为一个安全网或者终止非关键的本地资源,不应该在Finalizer或Cleaner里面包含任何业务代码.…
转文: 一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只有全面提升内存的管理效率,才能提高整个应用程序的性能.本文将从GC的工作原理.GC的几个关键问题进行探讨,最后提出一些Java程序设计建议,如何从GC角度提高Java程序的性能. 一.GC的基本原理: GC是什么? 为什么要有GC呢? GC是垃圾收集的意思(Garbage Collection),内存处理是编程人员容易出现问题的地方,忘…
优秀Java程序员必须了解的GC工作原理 一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只有全面提升内存的管理效率 ,才能提高整个应用程序的性能. 一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只有全面提升内存的管理效率 ,才能提高整个应用程序的性能.本篇文章首先简单介绍GC的工…
在STL中的容器中的析构函数中,会经常调用destroy()这个函数 在STL中  destroy()被重载了 这点在这里到不去讨论 这里贴最简单的那个版本 template<class T> inline void destory(T * pointer) { pointer->~T(); } 这里通过指针调用了析构函数.C++ 显示析构函数是一个怎么执行流程呢? 2点来讨论: 1)通过指针或者引用 2)通过值 #include <iostream> using names…
老生常谈的问题了,MSDN也有非常详细的说明但看起来不是很系统.也曾经做过分析,但没有总结下来又忘了,这次整理一下MSDN和网上搜集的一些资料,以备不时只需. 下面是MSDN对这两个函数的建议使用方法 MSDN建议 // Design pattern for a base class. public class Base : IDisposable { //保证重复释放资源时系统异常 private bool _isDisposed = false; // 析构函数,编译器自动生成Finaliz…
13.6 Why does a destructor in base class need to be declared virtual? 这道题问我们为啥基类中的析构函数要定义为虚函数.首先来看下面这段代码: class Foo { public: void f(); }; class Bar: public Foo { public: void f(); }; Foo *p = new Bar(); p->f(); 调用p->f()会调用基类中的f(),这是因为f()不是虚函数.为了调用派…
随着面向对象编程的普遍展开,面向对象展现了其中很多有趣的问题.相信很多初学者学习php面向对象时会接触两个函数,构造函数与析构函数.构造函数似乎用的更多,析构函数用的较少(相对初学者有限编程经验而言,笔者也是如此.)在功能上,构造函数在创建对象时调用,析构函数在对象销毁时调用,都无需特意去调用,一头一尾,倒也是前后照应. 析构函数常常处理的事务是一些资源释放的工作,比如前面有fopen(),这里调用fclose(),前面有imagecreatefromjepg(),这里调用imagedestor…
C++明确指出:当派生类对象是由一个基类指针释放的,而基类中的析构函数不是虚函数,那么结果是未定义的.其实我们执行时其结果就是:只调用最上层基类的析构函数,派生类及其中间基类的析构函数得不到调用. #include <iostream> using namespace std; class TimeKeeper { public: TimeKeeper(); ~TimeKeeper(); }; TimeKeeper::TimeKeeper() { cout << "Con…