我刚刚开始结合我对C ++类和动态数组的了解。我得到了“任何时候我使用新运算符”的建议我应该删除。我也知道析构函数是如何工作的,所以我认为这段代码是正确的:
的main.cpp
...
int main()
{
PicLib *lib = new PicLib;
beginStorage(lib);
return 0;
}
void beginStorage(PicLib *lib)
{
...
if (command != 'q')
{
//let's assume I add a whole bunch
//of stuff to PicLib and have some fun here
beginStorage(lib);
}
else
{
delete lib;
lib = NULL;
cout << "Ciao" << endl;
}
}
PicLib.cpp
...
PicLib::PicLib()
{
database = new Pic[MAX_DATABASE];
num_pics = 0;
}
PicLib::~PicLib()
{
delete[] database;
database = NULL;
num_pics = 0;
}
...
我用Pic
类填充我的PicLib,其中包含更多动态数组。 Pic
的析构函数以与上面相同的方式删除它们。我认为delete [] database
正确地摆脱了所有这些类。
那么 main.cpp 中的删除是否必要?一切看起来都很笨拙吗?
答案 0 :(得分:5)
有几个问题:
int main()
{
PicLib *lib = new PicLib;
beginStorage(lib);
return 0;
}
最好在同一范围内分配和删除内存,以便轻松发现。
但在这种情况下,只需在本地声明(并通过引用传递):
int main()
{
PicLib lib;
beginStorage(lib);
return 0;
}
在beginStorage()
中但我认为没有理由操纵指针。通过引用传递它,并在本地使用它。
void beginStorage(PicLib& lib)
{
....
}
在PicLib类中,您有一个RAW指针:数据库。
如果你有一个你拥有的RAW指针(你创建并销毁它),那么你必须覆盖复制构造函数和赋值运算符的编译器生成版本。但在这种情况下,我认为没有理由选择一个指针,使用矢量会更容易:
class PivLib
{
private:
std::vector<Pic> databases;
};
答案 1 :(得分:3)
是的,使用删除删除 new 创建的任何内容,以及使用 new [] 删除[] 删除必须。
我会在你的代码中指出一些事情:
答案 2 :(得分:2)
是的,这是必要的,除非你使用auto_ptr(并在使用之前阅读auto_ptr的语义 - 你不能复制它)。
例如:
int main()
{
auto_ptr<PicLib> lib = new PicLib;
beginStorage(lib);
return 0;
} // auto_ptr goes out of scope and cleans up for you
答案 3 :(得分:2)
else
不与while
一起使用。你想要更像的东西:
void beginStorage(PicLib *lib)
{
while (command != 'q')
{
//let's assume I add a whole bunch
//of stuff to PicLib and have some fun here
}
delete lib;
lib = NULL; // Setting to NULL is not necessary in this case,
// you're changing a local variable that is about
// to go out of scope.
cout << "Ciao" << endl;
}
delete
看起来不错,但您应该确保记录beginStorage
取得PicLib对象的所有权。这样,使用beginStorage
的任何人都知道他们以后不必删除它。
答案 4 :(得分:2)
main.cpp中的删除是必要的。
这可能是个人偏好的问题,但我建议不要在单独的逻辑部分中调用new和delete(这里PicLib实例上的delete调用是在一个单独的函数中)。通常最好只分配一部分分配和解除分配的责任。
@AshleysBrain有一个更好的建议(关于创建堆栈的PicLib),尽管如果PicLib占用太多内存,这可能会导致问题。
答案 5 :(得分:1)
通常你想要在新的地方删除。它使会计更容易。更好的是使用智能指针(在这种情况下为scoped_ptr),这意味着即使while的主体抛出异常并提前终止,您的代码仍然是正确的。
答案 6 :(得分:0)
一切看起来都不错。
main.cpp中的删除是必要的,因为如果你没有调用delete,那么析构函数不会运行,你的数组也不会被删除。你也会泄漏类的内存,而不仅仅是数组。
答案 7 :(得分:0)
是的,否则将不会调用PicLib的析构函数。
虽然有一个风格说明:如果您在函数中新建了一个方法范围对象,请尝试在同一个函数中删除它。作为一名初级工程师,他不得不经历大型项目来修复其他人的内存泄漏......这使得其他人阅读起来容易得多。从它的外观来看,你可以在beginStorage()返回后删除* lib。然后在一个地方更容易看到* lib的范围。