Tag: raii

C / C ++macros/模板blackmagic生成唯一的名称

macros是好的。 模板很好。 几乎无论它的工作是好的。 这个例子是OpenGL; 但该技术是C ++特有的,并且不依赖于OpenGL。 精确的问题: 我想要一个expression式E; 我不必指定一个唯一的名字; 这样一个构造函数在E被定义的地方被调用,并且一个析构函数被调用的地方在块E的末尾。 例如,考虑: class GlTranslate { GLTranslate(float x, float y, float z); { glPushMatrix(); glTranslatef(x, y, z); } ~GlTranslate() { glPopMatrix(); } }; 手动解决scheme { GlTranslate foo(1.0, 0.0, 0.0); // I had to give it a name ….. } // auto popmatrix 现在,我不仅为glTranslate,而且还有很多其他的PushAttrib / PopAttrib调用。 我宁愿不必为每个变种提出一个独特的名字。 是否有一些涉及macros模板的技巧…或其他什么东西会自动创build一个variables谁的构造函数在定义点被调用; […]

RAII与例外

我们在C ++中使用RAII的次数越多,发现自己的析构函数就越不重要。 现在,释放(最终确定,但是你想调用它)可能会失败,在这种情况下,exception确实是让楼上任何人知道我们的重新分配问题的唯一方法。 但是再一次,抛出析构函数是一个糟糕的主意,因为堆栈展开期间可能抛出exception。 std::uncaught_exception()可以让你知道什么时候发生了,但是除此之外,除了让你在终止之前logging消息之外,没有什么可以做的,除非你愿意让你的程序处于一个未定义的状态,有些东西被释放/定稿,有些则没有。 一种方法是有无抛出的析构函数。 但在很多情况下,这只是一个真正的错误。 例如,我们的析构函数可能会由于抛出一些exception而closures一些RAIIpipe理的数据库连接,而这些数据库连接可能无法closures。 这并不一定意味着我们可以在这个程序结束的时候继续。 另一方面,logging和追踪这些错误并不是每个案例的真正解决scheme, 否则我们就不需要例外了。 使用无抛析析构函数,我们也发现自己必须创build应该在破坏之前被调用的“reset()”函数,但是这只是打败了RAII的全部目的。 另一种方法就是让程序终止 ,因为这是你可以做的最可预测的事情。 有人build议链接exception,以便一次处理多个错误。 但是我真的从来没有真正看到过用C ++做的事情,我也不知道如何实现这样的事情。 所以它是RAII或例外。 不是吗? 我倾向于无耻的破坏者; 主要是因为它使事情变得简单(r)。 但我真的希望有一个更好的解决scheme,因为正如我所说的,我们使用RAII越多,我们就越发现自己使用的是不重要的东西。 附录 我添加链接到有趣的主题文章和我已经find的讨论: 投掷破坏者 关于SEH问题的 StackOverflow讨论 StackOverflow关于throwing-destructors的讨论(感谢,Martin York) 乔尔在例外 SEH被认为是有害的 CLRexception处理也涉及exception链接 草药Sutter对std :: uncaught_exception和为什么它没有你想象的那么有用 有关参与者的历史讨论 (长!) Stroustrup解释RAII Andrei Alexandrescu的范围卫队

在纯C中实现RAII?

纯粹的C可以实现RAII吗? 我认为这是不可能的,但也许有可能使用某种肮脏的伎俩。 重载标准的free函数会想到或者覆盖堆栈上的返回地址,这样当函数返回时,它会调用某个其他函数以某种方式释放资源? 或者,也许有一些setjmp / longjmp技巧? 这是一个纯粹的学术兴趣,我不打算写这样的不可移植和疯狂的代码,但我想知道这是否是可能的。

为什么在.NET中没有RAII?

主要是C ++开发人员,Java和.NET中RAII(资源获取初始化)的缺失一直困扰着我。 清理的责任从类作者转移到它的消费者(通过try finally或.NET的using构造 )的事实似乎显着地低下。 我明白了为什么在Java中不支持RAII,因为所有的对象都位于堆上,垃圾收集器固有地不支持确定性破坏,但是在引入值types( struct )的.NET中,我们有(看似)RAII的完美人选。 在堆栈上创build的值types具有明确定义的范围,并且可以使用C ++析构函数语义。 但是,CLR不允许值types具有析构函数。 我的随机searchfind了一个说法,如果一个值types被装箱,它属于垃圾收集器的pipe辖范围,因此其销毁变得不确定。 我觉得这个论点还不够强,RAII的好处足以说明一个具有析构函数的值types不能被装箱(或用作类成员)。 长话短说我的问题是 :有什么其他的原因价值types不能用于引入RAII到.NET? (或者你认为我关于RAII显而易见的优势的观点是有缺陷的?) 编辑:由于前四个答案已经错过了这个观点,我一定没有清楚地expression这个问题。 我知道 Finalize及其非确定性特征,我知道using构造,我觉得这两个选项比RAII差。 using是一个类的消费者必须记住的另一件事(有多less人忘记把一个StreamReader放在一个using块?)。 我的问题是关于语言devise的一个哲学问题,为什么它是这样,可以改进? 例如,对于generics确定性可破坏的值types,我可以使using和lock关键字是冗余的(可以通过库类实现): public struct Disposer<T> where T : IDisposable { T val; public Disposer(T t) { val = t; } public T Value { get { return val; } } ~Disposer() // Currently illegal { […]

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

什么是一些一般的技巧,以确保我不泄漏在C + +程序内存? 如何确定谁应该释放已dynamic分配的内存?

我是否需要手动closuresifstream?

当我使用std::ifstream时,是否需要手动调用close() ? 例如,在代码中: 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"); } 我需要手动调用file.close()吗? 不应该使用RAII来closures文件吗?

抛出C ++后调用析构函数吗?

我运行了一个示例程序,确实调用了堆栈分配对象的析构函数,但这是由标准保证的吗?

是否滥用IDisposable和“使用”作为获取exception安全的“范围行为”的手段?

我经常在C ++中使用的东西是让A类通过A构造函数和析构函数处理另一个类B的状态进入和退出条件,以确保如果该范围内的某个东西抛出一个exception,那么B就会知道当范围退出时状态。 就缩写而言,这不是纯粹的RAII,但是它仍然是一个确定的模式。 在C#中,我经常想要做的 class FrobbleManager { … private void FiddleTheFrobble() { this.Frobble.Unlock(); Foo(); // Can throw this.Frobble.Fiddle(); // Can throw Bar(); // Can throw this.Frobble.Lock(); } } 这需要做什么 private void FiddleTheFrobble() { this.Frobble.Unlock(); try { Foo(); // Can throw this.Frobble.Fiddle(); // Can throw Bar(); // Can throw } finally { this.Frobble.Lock(); } } 如果我想在FiddleTheFrobble返回时保证Frobble状态。 […]

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

请问C ++开发人员,请给我们一个关于RAII是什么的好的描述,为什么它很重要,以及它是否与其他语言有关联? 我确实知道一点点。 我相信它代表“资源获取是初始化”。 然而,这个名字并没有和我(可能是不正确的)理解RAII是什么关系:我得到的印象是,RAII是一种初始化堆栈上的对象的方法,当这些variables超出范围时,析构函数会自动被称为导致资源被清理。 那为什么不叫“使用栈来触发清理”(UTSTTC :)呢? 你怎么从那里到“RAII”? 而且你怎么能在堆栈上做些什么来清理堆上的东西呢? 另外,有没有不能使用RAII的情况? 你有没有发现自己希望收集垃圾? 至less有一个垃圾收集器可以用于某些对象,同时让其他人被pipe理? 谢谢。

C ++是否支持“终于”阻止? (我听说过这个“RAII”是什么?)

C ++是否支持“ 终于 ”阻止? 什么是RAII成语 ? C ++的RAII成语和C#的'using'语句有什么区别?