`
kuwoleft
  • 浏览: 1086941 次
文章分类
社区版块
存档分类
最新评论

C++的垃圾回收——以对象管理内存

 
阅读更多

1、以对象管理内存(Use Objects to manager resources.

这一条款主要说的是如何进行动态内存申请释放。

RAII原则:

<!--[if !supportLists]-->Ø <!--[endif]-->获得资源后立刻放进管理对象内;

<!--[if !supportLists]-->Ø <!--[endif]-->管理对象运用析构函数确保资源被释放;

我自己也写过一个动态申请释放的类。这个类的一个假设是,一个资源在被申请后会马上被使用,而在函数返回后就需要释放。为此我写了一个基类,每个资源类都要继承这个基类。每个资源子类的构造函数和析构函数都是private,这样就杜绝了newdelete操作。申请新的对象通过类的static函数来实现,不提供释放函数接口。基类中有一个static list,基类的构造函数会将this指针添加到这个list中。基类每隔5个循环就遍历一下list,看有没有待释放对象,如果有,则直接进行释放。

标准程序库auto_ptr类指针对象

应该是一个模板。

std::auto_ptr<Point> pInv(new Point(1));

Point是类指针对象指向的类。

pInv是类指针的变量名称。他后面的()中填写的类指针指向的类的引用。

void r_test()

{

std::auto_ptr<Point> pInv(new Point(1));

pInv->GetX();

}

之后,pInv就可以直接作为Point指针来使用。只不过它是局部变量,在函数返回是会释放。释放的时候,会进行Point的析构操作。

使用auto_ptr一定要防止多个指针指向一个对象,这样会造成多次释放。所以他有一个性质:若通过copy构造函数或者copy赋值函数复制他们,则他们本身会变成NULL,而复制所得指针会获得资源的唯一所有权。

注意:auto_ptrcopy赋值函数和copy构造函数的风险非常大。要少使用。

引用计数型智慧指针(RCSP

这个在linux好像没有(需要包含头文件#include <tr1/memory>)。

注意:

为了防止资源泄漏,请使用RAII(起源获取时机便是初始化时机——资源在构造期间获得,在析构期间释放)对象,他们在构造函数中获得资源,并在析构函数中释放资源。(使用的模板技术)

两个常被使用的RAIIclass分别是tr1::shared_ptratuo_ptr。前者通常是较佳选择,因为copy比较直观。若选择atuo_ptr,复制操作会使他(被复制物)指向NULL

2、在资源管理类中小心copying行为(Think carefully about copying behavior in resource-managing classes.

如果tr1::shared_ptratuo_ptr不适合作为资源管理类,则需要构造自己的资源管理类。

自己设计资源管理类时,也需要遵循RAII原则:

特别需要注意的一个问题是,RAII对象被复制时,会发生什么事情:

<!--[if !supportLists]-->1、 <!--[endif]-->禁止复制

<!--[if !supportLists]-->2、 <!--[endif]-->对底层资源使用引用计数法(reference count)通常,资源管理类只要内含一个tr1::shared_ptr成员变量,RAII就可以实现reference-counting copying行为。

tr1::shared_ptr默认情况下在删除的时候会delete相应的对象,但是,可以在构造时指定所谓的删除器,那是一个函数或者函数对象(而不是单纯的对象?什么是函数对象?),当应用次数为零时便被调用(此机制并不存在于auto_ptr——他总是将指针删除)。

<!--[if !supportLists]-->3、 <!--[endif]-->复制底部资源。也就是进行所谓的深度拷贝。

<!--[if !supportLists]-->4、 <!--[endif]-->转移资源的拥有权——就像auto_ptr一样。

注意:

复制RAII对象的时候必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的拷贝行为。

普遍而常见的RAIIclasses copying行为是:抑制copying,施行引用计数法。

3、<!--[endif]-->在资源管理类中提供对原始资源的访问(Provide access to raw resources in resource-managing classes.

RAII class需要一个函数可以见RAII classes 对象转化为其所内含的原始资源。

显示转换:

tr1::shared_ptrauto_ptr都提供get成员函数。用来执行显示转换。

另外,他们都提供了operator->operator*操作符,可以执行隐式转换。

尽量使用显示转换。

get函数与封装相矛盾,但是问题并不大。因为RAIIclass 主要的作用是为了资源释放。

“设计良好的类,会隐藏用户不需要看到的部分,当备妥客户需要看到的东西。”

注意:

APIs往往要求访问原始资源,所以每一个RAIIclass应该提供一个取得其所管理资源的方法。

对原始资源的访问可能经由显示转换和隐式转换,一般而言显示转换比较安全,但隐式转换相对比较方便。

分享到:
评论

相关推荐

    C++实例——垃圾清理系统

    本实例将深入探讨如何在C++中实现类似自动垃圾回收的功能,以避免内存泄漏和其他相关的编程错误。 首先,C++标准库并没有提供内置的垃圾清理系统,如Java或.NET中的垃圾收集器。在C++中,程序员需要手动管理内存,...

    搞定面试官:咱们从头到尾再说一次 Java 垃圾回收(csdn)————程序.pdf

    Java垃圾回收机制是Java虚拟机(JVM)中一个至关重要的功能,它负责自动管理内存,释放不再使用的对象,防止内存泄漏,从而优化程序性能。本文将深入探讨Java垃圾回收的相关知识点。 首先,GC(Garbage Collection...

    C++与Java——致即将学、正在学和学成的达内学子

    Java是一种纯面向对象的语言,其特性包括自动内存管理(垃圾回收)和强制类型检查。 1. 平台无关性:Java的运行环境JVM(Java虚拟机)使得程序可以在任何支持JVM的平台上运行,无需重新编译。 2. 自动内存管理:...

    Java中内存泄露及垃圾回收机制宣贯.pdf

    收机制在Java中,垃圾回收(Garbage Collection, GC)是一项自动管理内存的重要机制,它主要负责识别并清除不再使用的对象,从而释放内存资源。Java的垃圾回收机制是由虚拟机(JVM)的一部分——垃圾回收器(Garbage...

    浅析JAVA之垃圾回收机制.doc

    在Java编程中,与C++或C等语言相比,开发者无需手动管理内存,因为Java引入了一种自动的内存管理机制——垃圾回收(Garbage Collection,简称GC)。垃圾回收器负责监测并回收不再使用的对象所占用的内存空间,以防止...

    超越C++——C++/CLI

    C++/CLI的出现使得C++程序员能够利用.NET平台的功能,如垃圾回收、类型安全和跨语言互操作性,同时保持C++的高性能和灵活性。 C++/CLI的关键特性包括对CLI(Common Language Infrastructure)的集成,CLI是.NET框架...

    面向对象编程C++和Java比较教程 中英文完整版 pdf

    Java使用垃圾回收机制来自动释放不再使用的对象,避免了C++中的内存泄漏问题。Java也支持接口,这使得实现多继承成为可能,而C++只支持单继承。 在面向对象特性上,C++和Java都提供了封装、继承和多态。然而,C++的...

    虚拟机的设计与实现——C_C++

    7. **垃圾回收**:在虚拟机中,垃圾回收机制是自动管理内存的重要部分。通过C++的智能指针或其他机制,可以实现自动检测和释放不再使用的内存。 8. **性能优化**:虚拟机的性能优化包括指令级优化、内存访问优化...

    经典之谈——Java内存分配

    堆内存是所有线程共享的,通过垃圾收集器进行内存回收,以防止内存泄漏。 5. **方法区(元空间)**:存储类的元数据,如类名、字段信息、方法信息等。在Java 8之后,HotSpot虚拟机移除了永久代,将其替换为元空间,...

    安卓Android源码——代码调用C++代码和C++代码调用代码.zip

    - 内存管理:C++中需要手动管理内存,而Java由垃圾回收器自动管理,确保避免内存泄漏。 5. **性能优化** - 使用JNI调用C++代码可以提高性能,特别是对于计算密集型任务。 - 注意减少JNI调用的次数,因为每次调用...

    内存管理内存管理内存管理

    文中将为您提供如何管理内存的细节,然后将进一步展示如何手工管理内存,如何使用引用计数或者内存池来半手工地管理内存,以及如何使用垃圾收集自动管理内存。 为什么必须管理内存 内存管理是计算机编程最为基本的...

    浅谈内存泄漏(1)——内存泄漏的定义

    解决内存泄漏的方法包括采用智能指针来自动管理内存,使用垃圾回收(Garbage Collection)机制,或者编写更严格的代码审查和测试流程,确保在所有可能的退出路径上都正确地释放了内存和资源。在C++中,RAII...

    虚拟机的设计与实现——C/C++

    5. **内存管理**:涵盖对象分配、垃圾回收算法,如标记-清除、复制、标记-压缩和分代收集等。 6. **类型系统**:讲述虚拟机如何支持静态类型和动态类型,以及类型检查和转换。 7. **安全性与兼容性**:探讨如何...

    安卓Android源码——调用C++代码和C++代码调用源码.zip

    8. **内存管理**:在C++代码中,需要注意Java对象的生命周期管理,因为它们在JNI环境中可能不受常规垃圾回收机制管理。使用`NewLocalRef`和`DeleteLocalRef`管理临时引用,`NewGlobalRef`和`DeleteGlobalRef`管理跨...

    C++编程惯用法——高级程序员常用方法和技巧

    - 了解什么时候使用虚析构函数以及其对垃圾回收的重要性。 7. **Lambda表达式**: - 使用C++11引入的Lambda表达式简化函数对象的定义和使用。 - Lambda可以捕获上下文变量,方便地在异步操作、回调函数等场景中...

    垃圾清理系统

    通过这个小项目,我们可以深入理解内存管理、对象生命周期和垃圾回收的基本原理。 一、C++内存管理基础 C++是一种静态类型的、编译式的、通用的、大小写敏感的、不仅支持过程化编程,也支持面向对象编程的程序设计...

    java内存管理详细介绍.doc

    对于从事C、C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又是执行最基础工作的劳动人民——拥有每一个对象的“所有权”,又担负着每一个对象生命开始到终结的维护责任。希望本文档会给有...

    Java界面版 内存地址转换的三种方式过程演示

    对象内存布局则涉及到实例字段、对齐填充等,JVM会根据这些信息计算出对象的实际内存地址。 在“Java界面版 内存地址转换的三种方式过程演示”项目中,开发者可能创建了一个用户界面,用户可以通过这个界面触发不同...

    操作系统(内存管理)

    文中将为您提供如何管理内存的细节,然后将进一步展示如何手工管理内存,如何使用引用计数或者内存池来半手工地管理内存,以及如何使用垃圾收集自动管理内存。 为什么必须管理内存 内存管理是计算机编程最为基本的...

Global site tag (gtag.js) - Google Analytics