我的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 将超出范围,但我保留数据,因为被复制了? message
和details
char*
,以便在返回值ndb_error_struct超出范围时释放它们?
它很可能返回对数据成员的引用,您无需delete
它。
err
将是 getNdbError
返回值的副本,但由于它是一个堆栈变量,它将在作用域结束时被销毁 - 无需担心。
该函数返回对由 myObj
管理的对象的引用;可能是它的成员之一。您无需执行任何操作即可释放该对象; 当它被摧毁时,myObj
应该照顾它。
您正在使用返回的引用来初始化自动变量err
作为它的副本。像所有自动变量一样,当它超出范围时,它将被自动销毁。您也无需执行任何操作即可释放该对象。
但是,您可能也应该将myObj
设置为自动变量,除非您有充分的理由进行动态分配。如果有任何内容在 new
和 delete
之间引发异常,您的代码将出现内存泄漏。
getNdbError()
返回对NdbError
对象的 const 引用。 您不delete
引用。 你只delete
你new
编辑的东西。
您可以将getNdbError
的返回分配给具有自动生存期(而不是动态生存期)的NdbError
对象:
NdbError err=myObj->getNdbError();
err
这里是一个自动变量。 当它"超出范围"时,它将自动销毁。
有趣的是,如果您提供的代码与项目中的代码相同,则err
将在myObj
后销毁,您可以正确delete
。 如果err
和myObj
之间存在链接,这将导致err
析构函数中出现未定义的行为或其他一些不好的东西,因为myObj
不再存在,你可能不得不重新审视你的设计。
我强烈建议要么根本不使用动态分配,要么必须至少将其包装在 RAII 结构中,如智能指针,以便可以以更结构化的方式处理分配和解除分配。
函数const NdbError& getNdbError() const;
返回对NdbError
的常量引用。
您的NdbError err
副本将在函数结束时自动删除。
但是,与其复制,不如将其作为常量引用,即更改:
NdbError err=myObj->getNdbError();
自
const NdbError& err=myObj->getNdbError();
那么很明显,myObj
照顾了NdbError
的记忆.