在C++中,RAII是否总是在堆栈上分配对象,或者它是否曾使用堆?

Mag*_*nus -2 c++ raii

我想知道RAII是否总是在堆栈上分配,或者编译器是否曾将堆用于大型对象(然后可能会在堆栈中添加一个令牌作为提醒何时销毁相应的堆分配对象)?

更新:显然这个问题一直被认为不清楚.也许一个代码示例将使这更清楚:

在这段代码中:

void dosomething() {
    MyClass myclass();
}
Run Code Online (Sandbox Code Playgroud)

假设编译器没有优化这样一个简单的例子,那么由此创建的MyClass实例是否总是在堆栈上分配,或者堆是否曾经使用过?

我想我现在理解了答案,这要归功于接受的答案 - 答案似乎是类实例本身在堆栈上,而其内容可能会或可能不会取决于它的构造函数是如何定义的.如果这不正确,请添加评论/答案.

Jer*_*fin 6

请您谈一下RAII的方式使得它听起来就像你有一个错误的印象有关RAII什么最根本的想法的东西.RAII(也称为SBRM - 堆栈绑定资源管理,因此没有RAII至少与堆栈的概念完全不正交)基本上是一种编程风格.

使用RAII编写的程序可以并且经常从免费商店分配内存.然而,这种分配由某个类的对象处理.当对象被销毁时,类的析构函数执行,并释放动态分配的内存.

例如,一个典型的string对象只包含少量数据,例如指向字符串内容的指针和一个或两个整数来跟踪字符串大小.创建字符串时,它将从免费存储区分配一些空间来保存实际数据.当字符串被销毁时,它将自动释放该数据.在某些情况下,它有一些逻辑可以通过在字符串对象本身中分配一些小的(固定的)空间来避免小字符串的免费存储分配,但不会改变基本思想.

所以,真正的答案是合格的"是".是的,拥有一个包含指向堆上分配的数据的指针的小对象是相当普遍的.是的,当对象本身被销毁时,该对象将释放该内存.但不,这不是编译器你做事情.相反,它是您在设计和实现类时所做的事情.

  • 你的基本问题的答案是肯定的.大多数代码应该只使用自动存储来定义对象.不幸的是,你的例子是"最令人烦恼的解析":`MyClass myclass()`声明一个名为`myclass`的函数,返回类型为`MyClass`.要定义一个对象,你需要省略括号:`MyClass myclass;`. (2认同)