1

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

4

2 回答 2

1

许多程序员这样做:

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

(指针 = 我的工作)

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

但:

像这样的代码可能不赞成“裸指针”(这是非常主观的),所以有些人会说使用“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

于 2013-10-27T06:22:27.953 回答
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;
}
于 2013-10-27T06:38:08.703 回答