【问题标题】:in C++ does RAII always allocate objects on the stack or does it ever use the heap?在 C++ 中,RAII 总是在堆栈上分配对象还是使用堆?
【发布时间】:2014-07-06 19:08:51
【问题描述】:

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

更新:显然这个问题被认为是不清楚的。也许一个代码示例会使这一点更清楚:

在这段代码中:

void dosomething() {
    MyClass myclass();
}

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

我想我现在明白了答案,这要归功于接受的答案——答案似乎是类实例本身进入堆栈,而其内容可能会或可能不会取决于其构造函数的定义方式。如果这不正确,请添加评论/答案。

【问题讨论】:

  • RAII 和“堆栈”分配是完全正交的概念。
  • 堆栈分配就是堆栈分配,这就是重点。期间。
  • 那么RAII在哪里分配呢?用户可以指定吗?
  • 你应该阅读动态和自动分配RAII 不会干扰这两个概念,你走错了路。
  • @Magnus RAII 不分配任何地方。它与对象生命周期开始和结束时发生的事情有关,无论它在哪里分配。

标签: c++ raii


【解决方案1】:

您谈论 RAII 的方式听起来好像您对 RAII 的最基本概念有一些误解。 RAII(也称为 SBRM——堆栈绑定资源管理,因此没有 RAII 至少与堆栈的概念不完全正交)基本上是一种编程风格。

使用 RAII 编写的程序可以而且经常确实从空闲存储区分配内存。然而,这种分配是由某个类的对象处理的。当对象被销毁时,类的析构函数就会执行,从而释放动态分配的内存。

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

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

【讨论】:

  • 所以类实例化本身在堆栈中,而它的成员可能是基于类似 RAII 和传统的基于新/删除的成员的混合?换句话说,当我说 MyClass myclass();这个对象本身就在堆栈上,即使它的内脏不一定是?
  • 您的基本问题的答案是肯定的。大多数代码应该只定义具有自动存储的对象。不幸的是,您的示例是“最令人头疼的解析”:MyClass myclass() 声明了一个名为myclass 的函数,其返回类型为MyClass。要定义一个对象,您需要省略括号:MyClass myclass;
猜你喜欢
  • 1970-01-01
  • 2016-12-27
  • 2019-10-25
  • 1970-01-01
  • 2020-03-30
  • 2011-02-03
  • 2013-05-13
  • 1970-01-01
相关资源
最近更新 更多