标签: raii

260
推荐指数
10
解决办法
20万
查看次数

249
推荐指数
7
解决办法
7万
查看次数

从析构函数中抛出异常

大多数人都说永远不会从析构函数中抛出异常 - 这样做会导致未定义的行为.Stroustrup指出"向量析构函数显式地为每个元素调用析构函数.这意味着如果元素析构函数抛出,向量破坏失败......实际上没有好的方法来防止从析构函数抛出的异常,所以库如果元素析构函数抛出",则不保证"(来自附录E3.2).

这篇文章似乎另有说法 - 抛出析构函数或多或少都没问题.

所以我的问题是 - 如果从析构函数抛出会导致未定义的行为,那么如何处理析构函数期间发生的错误?

如果在清理操作期间发生错误,您是否只是忽略它?如果它是一个可能在堆栈中处理但在析构函数中不正确的错误,那么从析构函数中抛出异常是否有意义?

显然,这类错误很少见,但可能.

c++ destructor exception raii

246
推荐指数
10
解决办法
11万
查看次数

208
推荐指数
5
解决办法
5万
查看次数

RAII和C++中的智能指针

在使用C++的实践中,什么是RAII,什么是智能指针,如何在程序中实现这些以及将RAII与智能指针一起使用有什么好处?

c++ smart-pointers raii

189
推荐指数
4
解决办法
6万
查看次数

我需要手动关闭ifstream吗?

close()我使用时需要手动拨打电话std::ifstream吗?

例如,在代码中:

std::string readContentsOfFile(std::string fileName) {

  std::ifstream file(fileName.c_str());

  if (file.good()) {
      std::stringstream buffer;
      buffer << file.rdbuf();
      file.close();

      return buffer.str();
  }
  throw std::runtime_exception("file not found");
}
Run Code Online (Sandbox Code Playgroud)

我需要file.close()手动拨打电话吗?不应该ifstream使用RAII来关闭文件?

c++ raii ifstream

187
推荐指数
5
解决办法
6万
查看次数

避免C++内存泄漏的一般准则

有哪些一般提示可以确保我不会在C++程序中泄漏内存?我如何确定谁应该释放已动态分配的内存?

c++ memory memory-management raii

127
推荐指数
10
解决办法
12万
查看次数

理解术语和概念的含义 - RAII(资源获取是初始化)

您能否请C++开发人员详细介绍RAII是什么,为什么重要,以及它是否与其他语言有任何关联?

知道一点点.我相信它代表"资源获取是初始化".但是,这个名称并不符合我对RAII的理解(可能不正确):我得到的印象是RAII是一种初始化堆栈中对象的方式,当这些变量超出范围时,析构函数会自动被称为导致资源被清理.

那么为什么不称为"使用堆栈触发清理"(UTSTTC :)?你怎么从那里到"RAII"?

你怎么能在堆栈上创建一些东西来清理堆上的东西呢?此外,是否有不能使用RAII的情况?你有没有发现自己希望收集垃圾?至少一个垃圾收集器,你可以使用一些对象,同时让其他人管理?

谢谢.

c++ garbage-collection raii resource-management

108
推荐指数
7
解决办法
1万
查看次数

是否滥用IDisposable和"使用"作为获取异常安全的"范围行为"的手段?

我经常在C++中使用的东西是让一个类通过构造函数和析构函数A处理另一个类的状态入口和退出条件,以确保如果该范围内的某些东西抛出异常,那么B将具有已知状态范围已退出.就首字母缩略词而言,这不是纯粹的RAII,但它仍然是一种既定的模式.BA

在C#中,我经常想做

class FrobbleManager
{
    ...

    private void FiddleTheFrobble()
    {
        this.Frobble.Unlock();
        Foo();                  // Can throw
        this.Frobble.Fiddle();  // Can throw
        Bar();                  // Can throw
        this.Frobble.Lock();
    }
}
Run Code Online (Sandbox Code Playgroud)

这需要像这样做

private void FiddleTheFrobble()
{
    this.Frobble.Unlock();

    try
    {            
        Foo();                  // Can throw
        this.Frobble.Fiddle();  // Can throw
        Bar();                  // Can throw
    }
    finally
    {
        this.Frobble.Lock();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我想保证退货Frobble时的状态FiddleTheFrobble.代码会更好

private void FiddleTheFrobble()
{
    using (var janitor = new FrobbleJanitor(this.Frobble))
    {            
        Foo();                  // Can throw
        this.Frobble.Fiddle();  // Can throw …
Run Code Online (Sandbox Code Playgroud)

c# exception-handling raii

107
推荐指数
6
解决办法
6151
查看次数

为什么.NET中没有RAII?

作为一名C++开发人员,Java和.NET中缺少RAII(资源获取是初始化)一直困扰着我.清理的责任从班级作者转移到其消费者(通过try finally.NET的using构造)这一事实似乎显然是劣等的.

我明白为什么在Java中不支持RAII,因为所有对象都位于堆上,而垃圾收集器本身并不支持确定性破坏,但在.NET中引入了values-types(struct)我们有(看似) RAII的完美候选人.在堆栈上创建的值类型具有明确定义的范围,并且可以使用C++析构函数语义.但是,CLR不允许值类型具有析构函数.

我的随机搜索发现了一个论点,如果一个值类型被装箱,它就属于垃圾收集器的管辖范围,因此它的破坏变得不确定.我觉得这个论点不够强大,RAII的好处足以说明带有析构函数的值类型不能被装箱(或用作类成员).

简而言之,我的问题是:为了将RAII引入.NET,是否有任何其他原因无法使用值类型?(或者您认为我关于RAII明显优势的论点有缺陷吗?)

编辑:我必须没有明确表达这个问题,因为前四个答案已经错过了重点.我知道关于Finalize其不确定性的特点,我知道的using结构,我觉得这两个选项都逊色于RAII.using是一个阶级的消费者必须记住的另一件事(有多少人忘了把它StreamReader放在一个using街区?).我的问题是关于语言设计的哲学问题,为什么它是这样的,它可以改进吗?

例如,对于通用的确定性可破坏的值类型,我可以使usinglock关键字冗余(可以通过库类实现):

    public struct Disposer<T> where T : IDisposable
    {
        T val;
        public Disposer(T t) { val = t; }
        public T Value { get { return val; } }
        ~Disposer()  // Currently illegal 
        {
            if (val != default(T))
                val.Dispose();
        }
    }
Run Code Online (Sandbox Code Playgroud)

我忍不住以我曾经看过的apropos报价结束,但目前无法找到它的起源.

当我的冷死手超出范围时,你可以采取我的确定性破坏.- 匿名

.net struct destructor raii value-type

64
推荐指数
3
解决办法
7974
查看次数