const对象&从方法中返回值,最佳实践

时间:2013-11-08 14:26:42

标签: c++

我的C ++知识很少,因为我要问这个:

我有一个指向Ndb类型对象的指针,我这样做:

Ndb* myObj=new Ndb();
NdbError err=myObj->getNdbError();
//Do some work;
//Finish the job
delete(myObj);

getNdbError方法的签名是:

const NdbError& getNdbError() const

根据签名,谁必须照顾释放NdbError的记忆? const之前的NdbError&意味着我只能读取结果而我不应该做任何其他事情? 我不会留下一些分配但未引用的内存区域。

编辑: 根据ansers,它更好地展示了这个用例。我有一个C ++对象和C方法之间的包装器:

void* WINAPI new_Ndb(void* cluster_connection,const char* catalogname,const char* schemaName)
{

    Ndb_cluster_connection* co=(Ndb_cluster_connection*)cluster_connection;
    Ndb* tmpN=new Ndb(co,catalogname,schemaName);
    return (void*)tmpN;
}

void WINAPI Ndb_dispose(void* obj)
{
    delete (Ndb*)obj;
    obj=0;
}

const ndberror_struct WINAPI Ndb_getNdbError(void* obj)
{
    Ndb* tmp=(Ndb*)obj;

    NdbError res=tmp->getNdbError();    
    ndberror_struct tmpRes;
    tmpRes=(ndberror_struct)res;
    return tmpRes;
}

NdbError定义了一个运算符重载:

  operator ndberror_struct() const {
    ndberror_struct ndberror;
    ndberror.status = (ndberror_status_enum) status;
    ndberror.classification = (ndberror_classification_enum) classification;
    ndberror.code = code;
    ndberror.mysql_code = mysql_code;
    ndberror.message = message;
    ndberror.details = details;
    return ndberror;
  }

当我打电话给

时会发生什么

const ndberror_struct WINAPI Ndb_getNdbError(void* obj)?

Ndberror将超出范围但我保留数据因为被复制了? messagedetailschar*,因此当返回值ndb_error_struct超出范围时,它们将被释放?

4 个答案:

答案 0 :(得分:2)

它很可能会返回对数据成员的引用,您不需要delete它。

err将是getNdbError返回值的副本,但由于它是一个堆栈变量,它将在范围的末尾被销毁 - 无需担心。

答案 1 :(得分:1)

该函数返回对myObj管理的对象的引用;也许是其成员之一。你不需要做任何事来释放那个对象; myObj在销毁时应该照顾它。

您正在使用返回的引用初始化自动变量err作为它的副本。与所有自动变量一样,它会在超出范围时自动销毁。您也不需要做任何事情来释放该对象。

但是,您应该将myObj设为自动变量,除非您有充分的理由进行动态分配。如果有任何内容在newdelete之间引发异常,您的代码将会出现内存泄漏。

答案 2 :(得分:1)

getNdbError()返回对NdbError对象的const引用。你没有delete引用。您只需delete new编辑的内容。

您将getNdbError的返回值分配给具有自动生命周期的NdbError对象,而不是动态生命周期:

NdbError err=myObj->getNdbError();

err这是一个自动变量。它会在“超出范围”时自动销毁。

有趣的是,如果您提供的代码与项目中的代码相同,则err将在 myObj之后销毁deleteerr myObj 1}}正确。如果errmyObj之间存在链接,导致{{1}}的析构函数中存在未定义的行为或其他一些不良内容,因为{{1}}不再存在,您可能需要重温你的设计。

我强烈建议你根本不使用动态分配,或者你必须至少将它包装在像智能指针这样的RAII结构中,以便可以以更有条理的方式处理分配和释放。

答案 3 :(得分:1)

函数const NdbError& getNdbError() const;返回对NdbError的常量引用。

您的NdbError err副本将在功能结束时自动删除。

然而,不是复制它应该是一个恒定的参考,即改变:

 NdbError err=myObj->getNdbError();

 const NdbError& err=myObj->getNdbError();

然后很明显myObj会处理NdbError的内存。