草庐IT

c++ - 理解术语和概念的含义——RAII(Resource Acquisition is Initialization)

各位C++开发人员能否给我们一个关于什么是RAII的很好的描述,为什么它很重要,以及它是否可能与其他语言有任何相关性?我知道一点。我相信它代表“资源获取即初始化”。但是,该名称与我对RAII是什么(可能不正确)的理解不一致:我的印象是RAII是一种在堆栈上初始化对象的方法,这样,当这些变量超出范围时,析构函数将自动被调用导致资源被清理。那么为什么不叫“使用堆栈触发清理”(UTSTTC:)?你如何从那里到“RAII”?你怎么能在堆栈上做一些东西来清理堆上的东西?另外,是否存在无法使用RAII的情况?你有没有发现自己希望垃圾收集?至少有一个垃圾收集器可以用于某些对象同时让其他对象受到管理?

c++ - 尾调用优化和 RAII 可以共存吗?

我想不出真正的RAII语言在规范中也有尾调用优化,但我知道许多C++实现可以将其作为特定于实现的优化来实现。这对那些这样做的实现提出了一个问题:假设析构函数是在自动变量范围的末尾调用的,而不是由单独的垃圾收集例程调用,它是否违反了TCO的约束:递归调用必须是函数末尾的最后一条指令?例如:-#includeclasstest_object{public:test_object(){std::cout“Constructing...”将被写入999次,然后“Destructing...”又被写入999次。最终,在展开之前将自动分配999个test_object实例。但是假设一个实现有TCO

c++ - 尾调用优化和 RAII 可以共存吗?

我想不出真正的RAII语言在规范中也有尾调用优化,但我知道许多C++实现可以将其作为特定于实现的优化来实现。这对那些这样做的实现提出了一个问题:假设析构函数是在自动变量范围的末尾调用的,而不是由单独的垃圾收集例程调用,它是否违反了TCO的约束:递归调用必须是函数末尾的最后一条指令?例如:-#includeclasstest_object{public:test_object(){std::cout“Constructing...”将被写入999次,然后“Destructing...”又被写入999次。最终,在展开之前将自动分配999个test_object实例。但是假设一个实现有TCO

c++ - 如何处理 RAII 的构造函数失败

我熟悉RAII的优点,但我最近在这样的代码中遇到了一个问题:classFoo{public:Foo(){DoSomething();...}~Foo(){UndoSomething();}}一切正常,除了构造函数...部分中的代码引发了异常,导致UndoSomething()从未被调用。有一些明显的方法可以解决该特定问题,例如将...包装在try/catchblock中,然后调用UndoSomething(),但是:这是重复的代码和b:try/catchblock是我尝试通过使用RAII技术避免的代码异味。而且,如果涉及多个Do/Undo对,代码可能会变得更糟,更容易出错,我们必须中途

c++ - 如何处理 RAII 的构造函数失败

我熟悉RAII的优点,但我最近在这样的代码中遇到了一个问题:classFoo{public:Foo(){DoSomething();...}~Foo(){UndoSomething();}}一切正常,除了构造函数...部分中的代码引发了异常,导致UndoSomething()从未被调用。有一些明显的方法可以解决该特定问题,例如将...包装在try/catchblock中,然后调用UndoSomething(),但是:这是重复的代码和b:try/catchblock是我尝试通过使用RAII技术避免的代码异味。而且,如果涉及多个Do/Undo对,代码可能会变得更糟,更容易出错,我们必须中途

c++ - ScopeGuard 的使用真的会带来更好的代码吗?

我遇到了thisarticle多年前由AndreiAlexandrescu和PetruMarginean编写,其中介绍并讨论了一个名为ScopeGuard的实用程序类,用于编写异常安全代码。我想知道使用这些对象进行编码是否真的会导致更好的代码,或者它是否会混淆错误处理,因为也许守卫的回调会更好地呈现在catchblock中?有没有人有在实际生产代码中使用这些的经验? 最佳答案 它肯定会改进您的代码。您暂时提出的主张,即它是晦涩难懂的,并且代码可以从catchblock中获得值(value),这在C++中根本不正确,因为RAII是一个

c++ - ScopeGuard 的使用真的会带来更好的代码吗?

我遇到了thisarticle多年前由AndreiAlexandrescu和PetruMarginean编写,其中介绍并讨论了一个名为ScopeGuard的实用程序类,用于编写异常安全代码。我想知道使用这些对象进行编码是否真的会导致更好的代码,或者它是否会混淆错误处理,因为也许守卫的回调会更好地呈现在catchblock中?有没有人有在实际生产代码中使用这些的经验? 最佳答案 它肯定会改进您的代码。您暂时提出的主张,即它是晦涩难懂的,并且代码可以从catchblock中获得值(value),这在C++中根本不正确,因为RAII是一个

c++ - C/C++ 宏/模板 blackmagic 生成唯一名称

宏很好。模板很好。几乎任何工作都很好。例子是OpenGL;但该技术是特定于C++的,不依赖于OpenGL知识。精确问题:我想要一个表达式E;我不必指定唯一名称;这样在定义E的地方调用构造函数,在blockE结束的地方调用析构函数。例如,考虑:classGlTranslate{GLTranslate(floatx,floaty,floatz);{glPushMatrix();glTranslatef(x,y,z);}~GlTranslate(){glPopMatrix();}};手动解决方案:{GlTranslatefoo(1.0,0.0,0.0);//Ihadtogiveitaname

c++ - C/C++ 宏/模板 blackmagic 生成唯一名称

宏很好。模板很好。几乎任何工作都很好。例子是OpenGL;但该技术是特定于C++的,不依赖于OpenGL知识。精确问题:我想要一个表达式E;我不必指定唯一名称;这样在定义E的地方调用构造函数,在blockE结束的地方调用析构函数。例如,考虑:classGlTranslate{GLTranslate(floatx,floaty,floatz);{glPushMatrix();glTranslatef(x,y,z);}~GlTranslate(){glPopMatrix();}};手动解决方案:{GlTranslatefoo(1.0,0.0,0.0);//Ihadtogiveitaname

c++ - 如何防止通过 'new' 运算符分配类? (我想确保我的 RAII 类始终分配在堆栈上。)

我想确保我的RAII类始终分配在堆栈上。如何防止通过“new”运算符分配类? 最佳答案 您需要做的就是将类的新运算符声明为私有(private):classX{private://Preventheapallocationvoid*operatornew(size_t);void*operatornew[](size_t);voidoperatordelete(void*);voidoperatordelete[](void*);//...//TherestoftheimplementationforX//...};将“operat