在完成课程作业并学习C ++的过程中,我正在阅读何时使用堆栈分配和动态分配。我知道在很多情况下使用堆栈分配更容易也更好。但是有一个简单的情况我被困惑。
假设你有一个for循环:
for(int i = 0; i < 10; i++)
{
MyObject obj(file);
obj.doSomething();
}
现在的问题是,如果Object包含状态,它会保持状态(保持相同的对象),同时迭代从1到10的迭代。也许来自Java / C#背景让我走错了路。但我只看到两种方法来解决这个问题:
doSomething(file)
提供文件,但如果您有多个方法操作文件对象,这不是很好。 doSomethingElse(file)
。那么你们在这种情况下做了什么,或者你们从来没有让自己陷入这种境地?
更新 结果我误解了它并且按预期工作。检查下面的芒果!谢谢大家
答案 0 :(得分: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
答案 1 :(得分:1)
在此代码中,每次到达包含其声明的行并且在每次循环迭代结束时销毁它(它的析构函数被调用)时,都会创建obj
(其构造函数被调用)
如果你想创建它一次并让它在循环迭代中保存它的状态,那么在循环之外声明它:
MyObject obj(file);
for (int i = 0; i < 10; i++)
{
obj.doSomething();
}
如果您需要在多次迭代中使用相同的对象,并且您需要在迭代期间更改对象的状态(例如,通过更改文件),您将需要一些允许您更改的成员函数该状态(像useThisFile(file)
这样的专用成员函数或正在使用的成员函数的附加参数,如doSomething(file)
)。
答案 2 :(得分:0)
以下是否仍然会在周围的堆栈上分配您的对象并完成您的目标?
MyObject obj(file);
for (int i = 0; i < 10; i++)
{
obj.doSomething();
}
答案 3 :(得分:0)
在上面的代码中,obj是在循环的单个迭代的范围内创建的,并且在其结束时死亡。这就像在Java中一样,将MyObject obj = new MyObject()放在同一位置。没有信息会从循环的一次迭代过渡到另一次循环(除非你改变文件的状态)。
为了说服自己,将函数调用作为循环的“主体”。在该函数中,在堆栈上创建变量。该变量仅在执行此函数时生效。
答案 4 :(得分:0)
obj
在每次迭代结束时被释放 - 它的析构函数也会被调用十次。只要类的析构函数正确delete
由构造函数创建的任何东西,你就可以了。
在效率说明中,您可能只想在进入循环之前声明obj
一次。