2011-01-18 122 views
1

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

比方说你有一个循环:

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

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

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

那么你们在这种情况下做了什么,或者你从来没有陷入过这种状况?

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

+0

即使您使用动态内存替换了`MyObject obj(file);`,由于范围原因,您仍然不会保留状态。 – 2011-01-18 22:57:11

回答

5

在您发布的代码中,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 
+0

这将是我期望的行为,但是当我调试构造函数不被调用?使用VC++ – 2011-01-18 23:41:20

1

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

如果你想让它创建一次,并将它保存其状态在循环迭代,声明它的循环之外:

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

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

0

难道下面仍然不会在周围的堆栈上分配你的对象,并且完成你以后的事情吗?

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

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

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

0

obj在每次迭代结束时被取消分配---其析构函数也被称为十次。只要该类的析构函数正确delete由构造函数创建的任何东西,你都会好起来的。

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