管理从C ++函数返回的对象

时间:2013-10-27 06:14:03

标签: c++

我想知道如何从C ++函数返回一个新对象。例如,我有一个SQLite包装器,用于混合Objective-C,我将其修改为纯C ++。

所以,例如:

list<char*> * SqliteWrapper::RunQuery(const char *query)
{
       list<char*> * result = new list<char*>();

       //Process query

       return result;
}

我在这里可以看到的问题是谁拥有这个对象?调用类或创建对象的类?更糟糕的是,这很容易发生内存泄漏。如果调用者对象没有删除新创建的对象,则应用程序将最终导致内存泄漏。

现在我想到这一点,这很有道理:

int SqliteWrapper::RunQuery(const char *query, list<char*>& result)
{
       //Process query

       return errorCode;
}

还有其他方法吗?我有一段时间以来一直是C#程序员,现在才开始大量使用C / C ++。

2 个答案:

答案 0 :(得分:1)

许多程序员这样做:

如果它是一个返回的指针,我将被赋予对象的身份(它在内存中的位置是唯一的)我必须管理它。我有责任删除它。

(指针=我的工作)

然而,

引用让你假装你正在传递对象,看看和使用。你不负责删除这些,其他的是。

BUT:

“Naked pointers”对于像这样的代码(这是非常主观的)可能不赞成所以有些人会说使用“unique_ptr”,这些可以被移动,并删除它们在删除时指向的内容(除非这些东西是移出他们),通过返回一个而不使用它,它将被删除。

(告诉我,如果你想要我这样做,请参阅“shared_ptr”如果有多个东西有指针,这将删除指向它的最后一个shared_ptr被删除时指向的内容)

附录1

unique_ptr<list<char*>> SqliteWrapper::RunQuery(const char *query)
{
       list<char*> * result = new list<char*>();

       //Process query

       return make_unique<list<char*>>(result);
}

请记住,您只能移动,而不能复制unique_ptrs

答案 1 :(得分:0)

好。你是对的。

第一个例子是一个糟糕的风格,因为在这样的代码中几乎不可读,并且很难跟踪其中的错误。

通常人们使用第二种方法参考。 以同样的方式使用指针,在函数调用之前分配返回对象。

第三种方法是使用类而不是函数。如果您的函数使用许多参数执行复杂的过程,这很方便。在这种情况下,您将结果存储为类的数据成员,并且所有权显而易见:

class SqliteWrapper {
...
  class ProcessQuery {
    public:
      ProcessQuery():fQ(0),fP1(0){}
      SetQuery(const char *query){ fQ = query; }
      SetP1(int p1){ fP1 = p1; }
      ...

      list<char*> GetResult(){ return fR; } // copy

      int Run();
    private:
      const char *fQ;
      int fP1;
      ...

      list<char*> fR;
  }
...
}

int SqliteWrapper::Process::Run()
{
  //Process query

  return errorCode;
}