【发布时间】:2012-01-08 18:57:39
【问题描述】:
我在处理 C++ 程序中的内存方面没有经验,所以我想在这种情况下给我一些建议:
我想在一个类的函数中创建一个new Object,这在程序结束之前是必不可少的。就我而言,如果我使用运算符new,我有时应该删除它。考虑到它必须在一个类中初始化,我何时以及如何最终删除它?
【问题讨论】:
标签: c++ memory-management new-operator
我在处理 C++ 程序中的内存方面没有经验,所以我想在这种情况下给我一些建议:
我想在一个类的函数中创建一个new Object,这在程序结束之前是必不可少的。就我而言,如果我使用运算符new,我有时应该删除它。考虑到它必须在一个类中初始化,我何时以及如何最终删除它?
【问题讨论】:
标签: c++ memory-management new-operator
我建议智能指针习语
#include <memory>
struct X
{
void foo() { }
};
std::share_ptr<X> makeX() // could also be a class member of course
{
return std::make_shared<X>();
}
int main()
{
std::share_ptr<X> stayaround = makeX();
// can just be used like an ordinary pointer:
stayaround->foo();
// auto-deletes <sup>1</sup>
}
如果指针确实是一个静态变量,您可以替换为unique_ptr(其工作方式类似,但在赋值时传递所有权;这意味着指针不必保留引用计数)
注意要了解有关 C++ 智能指针的更多信息,请参阅 smart pointers (boost) explained
注意如果您没有 TR1/C++0x 对此的支持,您可以使用 Boost Smartpointer
1 除非您泄露 shared_ptr 本身的副本;这将是一些以前看不见的智能指针的奇怪用法:)
【讨论】:
std::shared_ptr?为什么不std::unique_ptr?
std::unique_ptr会存在?
std::shared_ptr,很少看到std::unique_ptr,我觉得std::unique_ptr应该比std::shared_ptr更普遍使用。
编辑:使用某种智能指针通常是个好主意,但我相信对 C++ 中的手动内存管理有一个扎实的理解仍然是必不可少的。
如果您希望类中的对象一直持续到程序结束,您可以简单地将其设为成员变量。从您所说的来看,没有什么建议您需要在这里使用new 或delete,只需将其设为自动变量即可。如果您确实想使用new 和delete 进行练习,您应该阅读constructors 和destructors 的类(您可以并且将使用new和delete 在课外,但我试图保持与您的问题相关)。这是我之前准备的:
class Foo
{
public:
Foo(); // Default constructor.
~Foo(); // Destructor.
private:
int *member;
}
Foo::Foo() // Default constructor definition.
{
member = new int; // Creating a new int on the heap.
}
Foo::~Foo() // Destructor.
{
delete member; // Free up the memory that was allocated in the constructor.
}
这是一个简单的示例,但希望能对您有所帮助。请注意,只要对象还活着,变量就会持续存在。如果对象被销毁或超出范围,将调用析构函数并释放内存。
【讨论】:
new 分配的内存。如果您要在堆上创建 Foo 的实例,例如Foo f = new Foo;,然后你必须在完成后致电delete f;。调用delete f; 会从堆中删除实例,但不会在调用f 的析构函数之前删除,这将删除member 整数使用的内存。
delete 一个指针时,您应该在之后将其设置为 0,这样您就不会意外引用已删除的内存。您不必担心在析构函数中将指针设置为 0,因为包含的对象正在被销毁。
您可以按照 Sehe 的建议使用智能指针,也可以在函数中创建一个静态对象并返回对它的引用。您不需要显式删除对象,当进程终止时,对象将被删除。喜欢:
struct X {};
X& makeX() // could also be a class member of course
{
static X x;
return x;
}
int main()
{
X& stayaround = makeX();
}
【讨论】:
在大多数操作系统(尤其是 Linux)上,如果您使用 new Object 分配对象指针,并且不要打扰 delete-ing,因为您在程序结束之前都需要它,真的不会造成任何伤害.您的程序内部存在一些内存泄漏(您可以使用valgrind 来寻找此类泄漏),但内核将在进程结束时释放进程使用的所有内存。
更好的选择是为应用程序数据设置一个单例类,例如QApplication 在 Qt 中,ahd 在您的 main 的早期构造该类中的单个实例,并让该类包含指向您的 Object 的智能或哑指针。析构函数应该delete 那个对象。
【讨论】:
Object 的全局实例?他要动态分配!!