抱歉,如果我的最后一个问题是非常相似的,但我有另一个查询何时以及如果我应该使用delete关键字。
示例代码。
初始化一个类,它的实参是指向vector的指针。这些对象从堆中分配内存。然后,我将这些对象传递给我的类构造函数,它也从堆中分配内存。
代码如下:在main函数
//This will also change each loop
vector<A*>* ex1 = new vector<A*>;
vector<B*>* ex2 = new vector<B*>;
vector<C*>* ex3 = new vector<B*>;
for(int i =0; i < 10; i++){
ex1->push_back( new A(i); );
ex2->push_back( new B(i); );
ex3->push_back( new C(i); );
}
MainClass* ex_main = new MainClass(ex1,ex2,ex3);
在MainClass.cxx MainClass::MainClass(vector<A*>* ex_A, vector<B*>* ex_B, vector<C*>* ex_C): m_ex_A(ex_A), m_ex_B(ex_B), m_ex_C(ex_C) {}
在MainClass.h vector<A*>* m_ex_A;
vector<B*>* m_ex_B;
vector<C*>* m_ex_C;
m_ex1、m_ex2和m_ex3已被赋值给堆栈,但已被赋值给指针指向向量的指针。
问题。
我删除m_ex_A,B和C在类MainClass的析析函数(我知道我将需要删除每个向量中的元素),也指针指向向量的指针在主函数?
e.x。在MainClass的析构函数中(我做了一些比这更通用的事情,但这更容易显示)
for(int i = 0; i < m_ex_A->size(); i++){
delete m_ex_A->at(i);
}
delete m_ex_A;
然后,我将在main函数中对指向指针ex1, ex2, ex3的向量的指针采取类似的方法,并删除main类。
我的困惑来自m_ex_A,B和C被分配给堆栈,而不是动态的,但他们被分配给动态对象的事实?
我的猜测是使用删除m_ex_A,B, C对象,因为我已经动态初始化他们?
还有什么更有效的使用堆内存或堆栈?
我想我可能使用了太多的动态内存
您一定应该在某处删除动态分配的对象。也可以在MainClass
的析构函数中这样做,但我个人认为这是一种糟糕的风格。为什么?因为你在不同的地方,不同的实体中进行分配和删除。事实上,你正在转移这些对象的所有权,所以你应该非常小心,不要删除两次之类的。我宁愿使用shared_ptr
或unique_ptr
,这样我就可以从所有这些微观管理中解脱出来。你可以在网上搜索它们,它们非常容易使用。
至于第二个问题——你必须只删除每个对象一次。复制指针并不会创建新对象,它只是指向同一个对象的另一个指针。
这不是对问题的直接回答,而是试图澄清潜在的问题:
概念上的问题是原始的指针不传递(更糟糕的是没有办法)所有权信息。它们只是一个指向内存位置的指针。现在,无论何时使用new
分配动态内存,您都有责任在某处删除它。决定它的位置是设计程序的一部分。如果你传递一个指针给某个对象,就像在你的例子中,你需要记录对象是否拥有指向内存的传递的所有权(在这种情况下,对象负责清理),或者如果它不(调用者仍然负责)。
使用原始指针,没有办法知道(除了文档或检查实现)任何给定的函数是否拥有所有权。
这就是新的c++ 11(也可以从boost中获得)智能指针(unique_ptr
和shared_ptr
)适合的地方。它们立即传达谁负责删除内存,甚至更好地自动处理(并且很少-或者在unique_ptr
的情况下没有-开销)
所以作为最后的指导方针:永远不要使用原始指针而不是智能指针或其他类型的RAII机制!(直到您获得了更多使用这些方法的经验,并且能够证明在这种特殊情况下,原始指针实际上是更好的解决方案)