【问题标题】:C++ loop stack allocationC++ 循环堆栈分配
【发布时间】:2011-06-11 10:08:18
【问题描述】:

在为课程分配作业并学习 C++ 时,我正在阅读有关何时使用堆栈分配和动态分配的信息。我知道在很多情况下使用堆栈分配更容易更好。但是有一个简单的情况让我很困惑。

假设你有一个 for 循环:

for(int i = 0; i < 10; i++)
{
   MyObject obj(file);
   obj.doSomething();
}

现在的问题是,如果对象包含状态,它会在从 1​​ 到 10 进行迭代时保持它的状态(保持相同的对象)。也许来自 Java/C# 背景让我走错了路。但我只看到两种解决方法:

  1. 使用动态内存。
  2. 不将文件提供给构造函数,而是提供给方法doSomething(file),但如果您有多个方法来操作文件对象,例如,这不是很好。 doSomethingElse(file).

那么你们在这种情况下会怎么做,或者你根本就不会让自己陷入这种情况?

更新: 原来我误解了,它按预期工作。检查下面的遮阳篷!谢谢大家

【问题讨论】:

  • 即使您将MyObject obj(file); 替换为动态内存,由于范围,您仍然不会保留状态。

标签: c++ stack memory-management


【解决方案1】:

在您发布的代码中,obj 在迭代之间不保持任何状态。

for(int i = 0; i < 10; i++) 
{    
  MyObject obj(file); //obj enters scope, constructor is called with 'file'
  obj.doSomething(); 
}  //obj loses scope, destructor is called

在那个例子中,obj 每次都是不同的对象。它可能使用与前一个对象相同的“堆栈”内存位置,但在迭代之间调用了类析构函数和构造函数。

如果您希望对象只构造一次并重复使用,请在循环之前构造。

function(file)
{
    MyObject obj(file); //obj enters scope, constructor is called with 'file'

    for(int i = 0; i < 10; i++) 
    {    
      obj.doSomething(); //Same object used every iteration
    }  

}  //obj loses scope, destructor is called

【讨论】:

  • 这将是我期望的行为,但是当我调试构造函数时没有调用?使用 VC++
  • 我会确保您处于禁用优化的调试模式 - 编译器可以优化调用。
【解决方案2】:

在这段代码中,obj 在每次循环到达包含其声明的行时创建(调用其构造函数),并在每次循环迭代结束时销毁(调用其析构函数)。

如果您希望它被创建一次并让它在循环迭代中保存其状态,请在循环之外声明它:

MyObject obj(file);
for (int i = 0; i < 10; i++)
{
    obj.doSomething();
}

如果您需要像这样在多次迭代中使用相同的对象,并且您需要在迭代期间更改对象的状态(例如通过更改文件),您将需要一些允许您更改的成员函数那个状态(或者像useThisFile(file)这样的专用成员函数,或者像doSomething(file)这样正在使用的成员函数的附加参数)。

【讨论】:

    【解决方案3】:

    以下内容不会仍然在周围的堆栈上分配您的对象并完成您所追求的吗?

    MyObject obj(file);
    for (int i = 0; i < 10; i++)
    {
      obj.doSomething();
    }
    

    【讨论】:

      【解决方案4】:

      在上面的代码中,obj 在循环的单次迭代范围内创建,并在其结束时死亡。这就像在 Java 中,您将 MyObject obj = new MyObject() 放在同一位置。没有信息会从循环的一个迭代过渡到另一个迭代(除非您更改文件的状态)。

      为了说服自己,请将函数调用作为循环的“主体”。在该函数中,在堆栈上创建变量。该变量仅在此函数执行时才存在。

      【讨论】:

        【解决方案5】:

        obj 在每次迭代结束时被释放——它的 destructor 也被调用了十次。只要类的析构函数正确deletes 构造函数创建的任何东西,你都会没事的。

        在效率方面,您可能只想在进入循环之前声明一次obj

        【讨论】:

          猜你喜欢
          • 2014-12-19
          • 1970-01-01
          • 2018-09-03
          • 2018-06-29
          • 2011-12-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-23
          相关资源
          最近更新 更多