如何解决C ++构造函数链接以创建/维护外部结构
我正在尝试使用python Ctypes接口到我提供的C ++类。在读取/写入成员数据和调用方法方面,我几乎已完成所有工作。但是Im试图锻炼的类(称为ClassA)依赖于外部类(称为classB)。看到:
//main.cc This is existing caller code. everything is c++ so using it is easy
include "ClassA.hh"
include "ClassB.hh"
void main() {
ClassB objB(x,y,z);
ClassA objA(a,b,&objB);
objA.DoStuff();
}
但是我还没有准备好通过ctypes绑定和公开python中的classB的工作。对于那些没有使用ctypes的人,您基本上可以编写一些C绑定,然后在python中调用它们。 A类绑定可能看起来像:
//at the bottom of ClassA.hh
extern "C" {
ClassA* ObjaNew(int x,int y) { return new ClassA(x,y);}
void ObjaDoStuff(ClassA* objPtr) { objPtr->DoStuff();}
}
然后python中的调用代码可能看起来像
mylib = ctypes.cdll('mylib.so')
myPyObj = mylib.ObjaNew(5,6) // executes ObjaNew
mylib.ObjaDoStuff(myPyObj) // executes ObjaDoStuff
重要的一点是python ctypes仅支持原生的c类型。通过Ctypes接口创建,传递或获取类或struct或std :: vector是可行的。例如:此链接是一个代码,需要分配该代码才能分配c ++向量:https://stackoverflow.com/a/16887455/2312509
所以,我想做的是:
//classA.hh
class ClassA{
public:
ClassA(int a,int b,ClassB* p_objb) { //This is the existing constructor
; //whatever
m_objb = p_objb;
}
ClassA(int a,int b) { // This is my new constructor
ClassB *objB = new ClassB(x,z);
ClassA(a,objB);
}
我已经做到了,并且可以编译,但是我还不能真正运行它。我担心的是objB被释放了,因为我看不到它是成员,尽管它是在构造函数的主体中分配的。我感觉好像是将对new的调用分配给成员数据指针,这是正确的,因为它是如何工作的,但是分配给本地指针,然后传递本地指针可能会失败。
我想我可以创建一个从两者继承的子类,例如:
ClassAB: public b():public a(){
//But the A constructor still would need to NOT rely on the existence of ObjB
m_objb = &this;
}
我还没有写过很多C ++,所以我不知道正确的答案是什么,但是我觉得这不是一个新概念。
解决方法
显然,您必须花一些时间来学习使用C ++处理对象的基础知识。
在这种情况下,我建议您执行以下操作:
class ClassA{
int m_a{};
int m_b{};
ClassB m_objb{};
public:
ClassA(int a,int b,ClassB &&p_objb)
: m_a{a},m_b{b},m_objb{std::move(p_objb)}
{
}
ClassA(int a,int b)
: ClassA(a,b,ClassB{x,y,z})
{
}
};
通过使ClassB成为Class A的成员,您不必担心内存分配或所有权,因为这是隐式的。
调用代码将如下所示:
ClassB objB(x,z);
ClassA objA(a,std::move(objB));
objA.DoStuff();
或更简单:
ClassA objA(a,ClassB(x,z));
objA.DoStuff();
最后一个明显表明ClassB仅用于构造ClassA,并且在移动后不能编写用法。
如果您想学习更多,我可以推荐我的另一篇文章,向了解Java的人解释相同的基础知识:https://codereview.stackexchange.com/questions/241354/remaking-a-1998-rts-game-in-c/241647#241647
,所以,我现在看来正在运行的是一个瘦接口类:
//classAInterface.cc
#include "classA.hh" // These are unchanged
#include "classB.hh"
class ClassAInterface {
public:
ClassAInterface(int a,int b);
ClassB *m_objb;
ClassA *m_obja;
};
ClassAInterface(int a,int b){
m_objb = new ClassB();
m_obja = new ClassA(a,m_objb);
}
extern "C" {
ClassAInterface* ObjaNew(int x,int y) { return new ClassAInterface(x,y);}
void ObjaDoStuff(ClassAInterface* objIntPtr) { objIntPtr->m_obja->DoStuff();}
}
// The python is the same
mylib = ctypes.cdll('mylib.so')
myPyObj = mylib.ObjaNew(5,6) // executes ObjaNew
mylib.ObjaDoStuff(myPyObj) // executes ObjaDoStuff
这似乎正在起作用,并且允许我实际上不更改要接口的类。它有一些缺点,因为我真正的ClassA依靠它的调用者来做某些事情的方式还有其他不愉快之处。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。