实例化对象C ++的堆栈和堆分配

时间:2016-05-07 04:42:28

标签: c++ pointers c++11 memory-management

我有一个C语言的背景,我试图了解C ++类以及如何在对象离开范围时调用析构函数。作为旁注,鉴于我想要做的事情的性质,我宁愿不使用像std :: array<>这样的STL结构。或std :: vector<>对于我在下面提供的数据容器。

以下是我理解的高级概述。鉴于某些课程:

class some_class{
    public:
        int * member;
        size_t n_members;

        some_class(size_t count) ...
        ~some_class() ...

        // a member function or operator overload
        // that returns an instance of some_class
        some_class do_something()
}

...

some_class * container;
// Some scope
{
    some_class foo = some_class();
    some_class * bar = new some_class();
    container[0] = bar;
}

some_class foo离开作用域时,会调用其析构函数。如果我想将指向some_class的实例的指针存储到作用域之外的container中,我需要在堆上实例化some_class bar,以便不会立即取消分配内存留下范围 - 就像我在C中那样。

现在,some_class的目的是保存大量数据,因此需要在堆上分配int * member

如上所述,some_class()的构造函数和析构函数将如下所示:

// some_class constructor
some_class::some_class(size_t count) : n_members(count){
    member = new int[count];
}

// some_class destructor
some_class::~some_class(){
    delete[] member;
}

现在我的问题变得明显了:如果我需要添加从some_class方法返回的do_something()实例,我保证会出现内存错误(在这种情况下,双重免费)因为do_something()返回堆栈分配的some_class

some_class * container = new some_class[n];
// Some scope
{
    some_class foo = some_class();
    some_class bar = foo.do_something();
    container[0] = &bar; // <-- I know this is stupid but that's the point of this question
}
delete[] container;

我的方法是让foo.do_something()返回指向some_class实例的指针。当然,不是解决方案。如何以真正的C ++方式正确解决这种情况?

例如,我一直在阅读的一件事是使用共享指针或唯一指针(或一般的智能指针)。但是,我的理解是使用这些指针需要您在堆中实例化您的对象。它对于要求foo.do_something()返回指针的整个问题也没有帮助。

无论如何,任何想法都会受到赞赏。

2 个答案:

答案 0 :(得分:0)

智能指针可用于将指针保存在some_class中,如下所示:

#include <memory>

class some_class{
  public:
    // smart pointer instead of raw pointer
    std::unique_ptr<int[]> member;
    size_t n_members;

    some_class(size_t count = 0) : member(new int[count]), n_members(count) {}

    // destructor not needed

    // a member function or operator overload
    // that returns an instance of some_class
    some_class do_something();
};

int main()
{
  int n = 3;
  // smart pointer instead of raw pointer
  std::unique_ptr<some_class[]> container(new some_class[n]);
  {
    some_class foo = some_class(10);
    some_class bar = foo.do_something();
    // use std::move to transfer pointer ownership
    container[0] = std::move(bar);
  }
  // no need to delete
}

答案 1 :(得分:-4)

我曾经精通C ++,但很久以前就转移到了Java,现在我的C ++生锈了:(。

您可以做的一件事是创建一个接受该类成员的构造函数。在其中,只需将属性复制到新实例。 (也可以使用静态方法而不是重载构造函数)。

some_class::some_class(some_class* obj){
    member = obj->member;
    n_members = obj->n_members;
}

所以你可以在代码中执行此操作:

some_class * container;
// Some scope
{
    some_class foo = some_class();
    some_class * bar = new some_class();
    container = new some_class(bar);
}

希望它适合你。