C ++构造函数链接以创建/维护外部结构

如何解决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 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-