-4

我总是在堆上动态分配;我已经完成了很多 Objective-C 编程以及普通 C 编程,并且由于我通常处理大块内存,所以堆对象是防止堆栈溢出所必需的。

最近有人告诉我,在 C++ 中不鼓励使用动态分配的对象,应尽可能使用堆栈对象。为什么是这样?

我想说明这一点的最好方法是举例:

Class *_obj1;
Class *_obj2;

void doThis(Class *obj) {}

void create() {
    Class *obj1 = new Class();
    Class obj2;

    doThis(obj1);
    doThis(&obj2);

    _obj1 = obj1;
    _obj2 = &obj2;
}

int main (int argc, const char * argv[]) {

    create();

    _obj1->doSomething();
    _obj2->doSomething();

    return 0;
}

这将创建 2 个对象,将它们存储在指针中,然后main()在每个对象上调用一个方法。该Class对象创建 achar*并将 C 字符串存储"Hello!"在其中;释放~Class()器释放内存。该方法使用doSomething()打印出来。很简单。现在让我们运行它:"buff: %s"printf()

Dealloc
Buff:你好!
增益:¯ø_ˇ

哇,怎么了?即使我们存储了指向它的指针,C++ 也会释放_obj2它;那是因为它在堆栈上而不是堆上,而且 C++ 没有像 Objective-C 那样的保留计数机制(我尝试一次实现一个;它工作得很好,但我不想将它作为超类添加到所有内容中)。所以我们必须在函数返回后跳过箍来保持它。

4

3 回答 3

5

考虑“更简单”的类型,而不是对象。你会这样做吗:

void create() {
    int *obj1 = new int();
    int obj2;

    _obj1 = obj1;
    _obj2 = &obj2;
}

你认为这会奏效吗?显然不是。这很简单。您不能传递指向分配给堆栈的对象的指针(并且,根据经验,您不应该传递指向刚刚分配的对象的指针。如果有人分配了一个对象,他有责任释放它)

于 2011-02-20T09:43:48.933 回答
1

堆对象本身并没有错,管理它们的生命周期是错误的。

堆栈对象具有无论代码如何离开函数(异常、返回值)都将调用其析构函数的属性。智能指针利用它来管理堆分配对象的生命周期(一个快乐的媒介?)

于 2011-02-20T09:47:12.130 回答
1

C++的一个基本设计原则是不用为不用的东西付费,这样C++就可以用来编写高度优化的代码。无论您使用哪种语言,堆栈分配都更有效。

于 2011-02-20T09:50:56.417 回答