如何在c函数中创建一个新对象并传递对它的引用
How to create a new object in a c function and pass a reference to it?
我的问题的实质是:
在c函数中创建一个新对象并将对该新对象的引用传递给调用者的最佳方法是什么?我的整体设置有点复杂,涉及混合c和c++代码,所以我包括一些背景信息:
我正在为3D引擎创建一个c++库。该库旨在从不同平台的主机应用程序中使用。
为了便于兼容,我现在打算将所有c++代码隐藏在纯c的API后面。
我唯一不确定的是,这是最好的方式实际上创建我的引擎实例通过我的c API。
我的第一个方法是:
// in myEngineAPI.h
void myEngineCreate(void * myEngine);
void myEngineRelease(void * myEngine);
// in myEngineAPI.cpp
#include "myEngineAPI.h"
#include "myPrivateCppEngine.h"
void myEngineCreate(void * myEngine) {
myEngine = new Engine; // <- this doesn't seem to work as expected
}
void myEngineRelease(void * myEngine) {
delete ((Engine *)myEngine);
}
// in my host application
#include "myEngineAPI.h"
void * myEngine = NULL;
myEngineCreate(myEngine); // <- problem: myEngine is still NULL after this line.
// ...draw some fancy stuff...
myEngineRelease(myEngine);
我希望myEngineCreate(void * myEngine)
将我新创建的对象的地址分配给myEngine
。但是在函数返回后,myEngine
仍然指向NULL。为什么?
现在我的第二个方法是:
// in myEngineAPI.h
void * myEngineCreate();
void myEngineRelease(void * myEngine);
// in myEngineAPI.cpp
#include "myEngineAPI.h"
#include "myPrivateCppEngine.h"
void * myEngineCreate() {
return new Engine; // <- ok, the function returns a valid pointer
}
void myEngineRelease(void * myEngine) {
delete ((Engine *)myEngine);
}
// in my host application
#include "myEngineAPI.h"
void * myEngine = myEngineCreate(); // <- yay, I have a void pointer to my engine
// ...draw some fancy stuff...
myEngineRelease(myEngine);
这工作。myEngineCreate()
给了我一个不透明的指针指向我的引擎实例,我可以在我随后的绘图调用中使用,我也可以交给我的释放函数,当我用它完成时清理内存。这种方法的问题是,我的分析器抱怨myEngineCreate()
中的内存泄漏。我明白,在一个地方创造一个对象,在另一个地方拥有它是一件微妙的事情,我在这里似乎做错了什么——但是什么?
提前感谢您的建议和帮助
以myEngineCreate
函数为例:
void myEngineCreate(void * myEngine) {
myEngine = new Engine;
}
这不起作用,因为myEngine
是myEngineCreate
函数范围内的局部变量。通过引用传递一个指针在C语言中,你必须把它作为一个指针传递给另一个指针,然后使用解引用操作符给指针赋值:
void myEngineCreate(void ** myEngine) {
*reinterpret_cast<Engine**>(myEngine) = new Engine;
}
通过使用指针的地址操作符&
来调用它:
void * myEngine;
myEngineCreate(&myEngine);
作为最后的补充,另一个可能的解决方案是返回新指针:
void* myEngineCreate() {
retur reinterpret_cast<void*>(new Engine);
}
在c函数中创建一个新对象并将对该新对象的引用传递给调用者的最佳方法是什么?在C语言中,最好的面向对象的方法是创建一个不复杂类型的对象,也称为不透明类型(void指针不是不透明类型,它只是一个原始地址)。
的例子://engine.h
typedef struct engine_t engine_t;
engine_t* engine_create (void);
//engine.c struct engine_t
{
/* all variables placed here will have true private encapsulation */
};
engine_t* engine_create (void)
{
return malloc(sizeof(engine_t));
}
//c int main()
{
engine_t* my_engine = engine_create();
}
这是C语言中真正的面向对象,在没有c++语言支持的情况下可以实现的最佳OO。调用方将无法访问该结构体的任何成员。
但是函数返回后,myEngine仍然指向NULL。为什么?
因为指针本身在C和c++中是按值传递的。你要么传递指针的地址,要么将指针返回给调用者。关于这个主题的许多问题和常见问题可以在SO.
我使用不透明指针做了类似的事情:
typedef struct my_c_engine *myCEngine;
extern "C" myCEngine createEngine() {
return reinterpret_cast<myCEngine>(new myRealEngineClass());
}
extern "C" void releaseEngine(myCEngine c) {
if(c) {
myRealEngineClass *x = reinterpret_cast<myRealEngineClass*>(c);
delete x;
}
}
我这样做是因为我想让C部分完全隔离。
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 我们可以有一个 setter 成员函数作为从 const 对象引用的 const 吗?
- C++对象引用返回不同的值
- 对象引用中的字段以不同的方法返回不同的值
- 通过向构造函数其他对象引用页面来创建对象
- 为什么在对象引用恒定时允许更改为另一个类的指针的成员变量
- 如何在C++中读取 HDF5 对象引用
- C++ 未定义的对象引用
- 从函数返回 libconfig 类设置对象引用
- qt vsaddin错误对象引用未设置为对象的istanse
- 在这种情况下,为什么使用 *此必需的对象引用返回对象引用
- 基本C - 构造contaning对象引用,并将其作为方法参数传递
- C :将对象引用作为参数给出错误:呼叫class :: function()的匹配函数
- C++OOP基础知识-是否正确返回对象引用
- 使用对象引用(可能)在调用destructor后使用对象引用
- 创建返回对象引用的成员函数的最简单方法
- 如何在C++上使用对象引用删除对象
- JNI/Android NDK-维护全局对象引用
- 为什么有些类方法返回"*this"(self的对象引用)?
- 在C++中返回伪对象引用的规则