const object&return value from a method, best practice



我的C++知识很少,为此我问:

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

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

该方法的getNdbError签名为:

const NdbError& getNdbError() const

根据签名,谁必须为NdbError释放内存? NdbError&之前的const意味着我只能阅读结果,而不应该阅读其他任何东西?我不会留下一些分配但不引用的内存区域。

编辑:根据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 将超出范围,但我保留数据,因为被复制了? messagedetails char*,以便在返回值ndb_error_struct超出范围时释放它们?

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

err将是 getNdbError 返回值的副本,但由于它是一个堆栈变量,它将在作用域结束时被销毁 - 无需担心。

该函数返回对由 myObj 管理的对象的引用;可能是它的成员之一。您无需执行任何操作即可释放该对象; 当它被摧毁时,myObj应该照顾它。

您正在使用返回的引用来初始化自动变量err作为它的副本。像所有自动变量一样,当它超出范围时,它将被自动销毁。您也无需执行任何操作即可释放该对象。

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

getNdbError()返回对NdbError对象的 const 引用。 您不delete引用。 你只deletenew编辑的东西。

您可以将getNdbError的返回分配给具有自动生存期(而不是动态生存期)的NdbError对象:

NdbError err=myObj->getNdbError();

err这里是一个自动变量。 当它"超出范围"时,它将自动销毁。

有趣的是,如果您提供的代码与项目中的代码相同,则err将在myObj销毁,您可以正确delete。 如果errmyObj之间存在链接,这将导致err析构函数中出现未定义的行为或其他一些不好的东西,因为myObj不再存在,你可能不得不重新审视你的设计。

我强烈建议要么根本不使用动态分配,要么必须至少将其包装在 RAII 结构中,如智能指针,以便可以以更结构化的方式处理分配和解除分配。

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

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

但是,与其复制,不如将其作为常量引用,即更改:

 NdbError err=myObj->getNdbError();

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

那么很明显,myObj照顾了NdbError的记忆.

相关内容

最新更新