0

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

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

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

该方法的签名为getNdbError

const NdbError& getNdbError() const

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

编辑:根据分析,最好展示更多这个用例。我有一个 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 将超出范围,但我保留数据是因为被复制了吗? 当返回值 ndb_error_struct 超出范围时,它们会被释放messagedetailschar*

4

4 回答 4

2

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

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

于 2013-11-08T14:28:48.323 回答
1

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

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

NdbError err=myObj->getNdbError();

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

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

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

于 2013-11-08T14:33:24.183 回答
1

该函数const NdbError& getNdbError() const;返回一个对NdbError.

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

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

 NdbError err=myObj->getNdbError();

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

那么很明显,它myObj会照顾NdbError.

于 2013-11-08T14:36:35.663 回答
1

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

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

但是,您可能也应该创建myObj一个自动变量,除非您有充分的理由进行动态分配。new如果有任何东西在和之间引发异常,您的代码将发生内存泄漏delete

于 2013-11-08T14:30:35.933 回答