我在堆栈上创建了一个简单的Dummy对象数组:
Dummy a(8);
Dummy b(9);
Dummy dummies[2] = {a,b};
有一个MyObject对象。我在堆栈上创建了它。构造函数将此数组存储到实例变量中。
class MyObject{
Dummy* _dummies;
MyObject obj(Dummy* dummies):
: _dummies(dummies)
{
}
};
MyObject obj(dummies);
当obj被删除并且它的析构函数被调用时,_dummies的记忆被释放了吗?我理解堆栈上的实例变量是自动释放的,但是MyObject如何知道这个指针指向堆栈上的数组而不是堆上创建的Dummy对象?
在构造函数中是通过值或引用传递的虚拟数组?它是一个指针,但它毕竟是堆栈中的一个数组。
我理解堆栈,堆,传递值和引用,但是使用指针处理的堆栈上的数组确实让我很困惑。我一直使用vector,因为它清晰简单,但我也想理解简单的数组。
编辑:谢谢大家。现在我明白MyObject与数组的生命周期没有任何关系。当dummies阵列超出范围时,它会被删除。但是:如果用“char”代替“Dummy”怎么办?在堆栈上有一个char *(例如从函数返回)是非常标准的,并将它传递给一个对象,然后只需将指针保存到第一个char就可以存储它。这也是一个不好的做法吗? (我将使用std :: vector和std :: string代替,更简单......)
答案 0 :(得分:1)
你需要知道你的实例变量_dummies只是一个指针。创建对象时,传递给构造函数的指针存储在_dummies中,这就是全部。该指针可以是NULL,堆栈上的数组地址,malloc返回的指针,或许多其他东西。你的对象不知道。
如果在对象仍然存在时数组消失,那么在此之后使用该对象时会遇到麻烦。您有责任确保数组仍然存在,直到最后一次访问对象中的_dummies为止。并且您负责在对象消失后以某种方式删除数组本身。因此,除非您仔细使用,否则您的构造稍微处于危险的一面并且会崩溃。
答案 1 :(得分:0)
唯一的问题是,如果您在new
课程中使用了Dummy
。如果你没有,不需要担心。当堆栈中的对象超出范围时,它们会自动删除。
答案 2 :(得分:0)
当obj被删除并且它的析构函数被调用时_dummies的记忆被释放了吗?
不,但这不是问题,如果我理解你的例子,因为_dummies'的记忆。在堆栈上,当它超出范围时将被释放(独立于被销毁的MyObject实例)。
我理解堆栈上的实例变量是自动释放的,但是MyObject如何知道这个指针指向堆栈上的数组而不是堆上创建的Dummy对象?
它没有。如上所述,MyObject析构函数不会自动释放_dummies指向的任何已分配内存。
在构造函数中是通过值或引用传递的虚拟数组?它是一个指针,但它毕竟是堆栈中的一个数组。
它是堆栈上的数组,而不是指针。当在表达中使用它时,它会衰变。到指针(指向数组中的第一个元素)。因此,它通过引用传递(但不是作为C ++引用!)。
答案 3 :(得分:0)
当obj被删除并且它的析构函数被调用时_dummies的记忆被释放了吗?
不,不是。如果你想释放与任何指针相关的内存,你必须明确地这样做,例如如果delete[] _dummies
是动态数组,请键入_dummies
。
MyObject如何知道这个指针指向堆栈上的数组而不是指向堆上创建的Dummy对象?
它没有。这意味着如果您在堆栈分配的_dummies
超出范围后尝试访问MyObject
中的Dummy dummies[2] = {a,b};
并被删除,则可能会出现段错误。
在构造函数中是通过值或引用传递的虚拟数组?
它的类型Dummy[]
被强制转换为指针类型Dummy*
,然后按值传递。
答案 4 :(得分:0)
您的Dummy* _dummies;
成员变量可能会也可能不会指向某个实际的内存位置。管理此位置是您的责任,而不是默认构造函数。因此,如果使用类外部的指针初始化它,当实例被销毁时,指向的内存不会发生任何事情,只是指针会消失。如果在类中创建(新)实例,则必须在析构函数中释放(删除)它。
从实际的角度来看,您可能需要考虑智能指针,例如C ++ 11中的std :: shared_ptr,以使这些任务不易出错。