const object&return value from a method, best practice
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 将超出范围,但我保留数据,因为被复制了? 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
的记忆.
- 通过 get-Method 访问变量在类外不起作用
- 为什么我的 BaseClass:Method 代码编译(带有单冒号)?
- 如何在 c++ 中理解这样的代码 [request->headers().Method()->value().getStringView())]
- g++ [[noreturn]] on a virtual method
- 错误"pure virtual method called",当此方法已被覆盖时
- 如何修复此错误? "Method 'str' could not be resolved"
- 使用 -march 编译会导致线程说"pure virtual method called"
- QMetaObject::invokeMethod: no such method QTextCursor::MoveO
- ":"(单个冒号)在"Klass:method(p)"中是什么意思?
- LuaJIT 和 C++ - 调用 Table.Method() 在 loadstring/pcall 中不起作用
- 如何在源文件中定义类并将其声明在标题文件中(而不必使用`class :: method'语法定义类方法)
- C++ 使用 .chain().method() 链接成员函数 vers ->chained(0->method()
- OpenCV InputArray and getMat method
- Eclipse "implement method"函数不适用于模板类
- Typedef for static method
- cuda convnet equvilent method from opencv gpu::convolve
- (*it)->method() vs (**it).method
- std::stringstream and the str method
- Clang的措辞中"annotated fallthrough"和"partly annotated method"是什么?
- const object&return value from a method, best practice