首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Qore对偶类实现( C++ /Qore)与从C++核调用虚拟方法

Qore对偶类实现( C++ /Qore)与从C++核调用虚拟方法
EN

Stack Overflow用户
提问于 2017-02-17 20:53:45
回答 1查看 99关注 0票数 2

我需要在QoreFoo中实现C++类,并通过.qpp实现Qore脚本Foo的双重实现。QoreFoo是提供通用API的抽象类,实际功能将在子类和类中添加(在C++或Qore中)。来自核心i.e.C++的Foo调用需要传播到实例化对象,而不管在何处使用子类。

QoreFoo.h

代码语言:javascript
复制
# implement general API

class QoreFoo {
public:
  virtual void bar(ExceptionSink *xsink)=0; 
};

extern QoreFoo* current_foo;

// just assign instance of a descendant of QoreFoo 
void QoreAssignFoo(QoreFoo* n_foo) {
  current_foo = n_foo;
}

QoreFoo.cpp

代码语言:javascript
复制
QoreFoo* current_foo = 0;

any.cpp

代码语言:javascript
复制
if (current_foo)
  current_foo.bar(xsink);  // propagate call via overriden method

当我需要实现C++后代时,这是微不足道的:

QoreFoo2.h

代码语言:javascript
复制
class QoreFoo2: QoreFoo {
  void bar(ExceptionSink *xsink) {
    # my stuff
    printf("Hello World from C++");
  }
};

usage.cpp

代码语言:javascript
复制
QoreAssignFoo(new QoreFoo2);
# wait for "Hello World from C++" when core calls current_foo.bar()
.....

但是如何将调用传播到Qore脚本类?我认为需要额外的类来调用.qpp中定义的对偶类和.q中的overriden类。

QoreFooHelper.h

代码语言:javascript
复制
class QoreFooHelper: class QoreFoo {
private:
  QoreObject* qo;
public:
  QoreFooHelper(QoreObject* n_qo): qo(n_qo) {
  }
  void bar(ExceptionSink *xsink) {
    // convert args if any
    // call virtual function of Foo class, i.e. qo 
    qo->evalMethod("bar", 0, xsink);
  }

QC_Foo.qpp

代码语言:javascript
复制
# implement assign instance function
nothing assignFoo(*Foo foo) {
  QoreAssignFoo(foo->p);
}

#implement class for Qore script
qclass Foo [arg=QoreFooHelper* p]

Foo::constructor() {
  assert(self->validInstanceOf(CID_FOO));   // is it correct test to test if inherited from ?
  QoreFoo* f = new QoreFooHelper(self);
  self->setPrivate(CID_FOO, f);
}

# probably useless as it generates function code
#nothing Foo::bar() {
#}

Test.q

代码语言:javascript
复制
class Foo2 inherits Foo {
  nothing bar() {
    # my stuff
    printf("Hello world from Q");  
  }
}

Foo2 foo();
assignFoo(foo);  # assign instance of Foo2
# wait for "Hello World from Q" message when core calls current_foo.bar()
....

这个可行的解决方案,或者甚至存在一个更好的方法,例如使用qpp特性或避免QoreFooHelper (但我需要避免在C++中完全实现QoreFoo2时的开销)?

如果不是,那么什么是替代选择,例如以某种方式传递回调或闭包并执行真正的回调?

编辑:

在.qpp中定义Qore类时,qpp生成类定义QoreClass* initFoo() (添加方法、构造函数等)并将其注册到命名空间存储库中。

当要创建新的QoreObject时,将使用QoreClass作为参数来构造命名空间回购。

.qpp定义的构造函数通常创建纯C++ QoreFoo实例,并将其赋值为私有属性(self->setPrivate(CID_FOO,新的QoreFoo (),即建立了从Foo到QoreFoo的链接,并将在定义.qpp方法时使用。.qpp在函数"header“中生成了适当的C++代码。self是QoreObject实例。

我认为Foo3脚本类在运行时也是如此。

Qpp帮助实现Qore来调用C++。

但是我需要相反的方向,从C++调用Qore方法,所以我认为我需要调用QoreObject::evalMethod()。由于QoreObject不存在于普通的C++类中,所以需要额外的子代QoreFooHelper来实现它(在将一般对象作为参数传递时存在额外的问题)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-17 22:10:52

如果要执行的API是Qore语言类API,则需要在Qore而不是C++中实现抽象类。

如果您有一个应该在Qore中扩展的C++虚拟类层次结构,那么您应该使用qpp在C++中实现您的Qore类,然后允许程序员通过在Qore中子类来自然地扩展它。

你可以这样做:

QoreFoo.h

代码语言:javascript
复制
class QoreFoo {
public:
     DLLLOCAL QoreFoo(QoreObject* o) : obj(o) {
     }
     // other functions...
private:
     QoreObject* obj;  //!< The QoreObject this private data is associated with
};

QC_Foo.qpp

代码语言:javascript
复制
//! This class defines an abstract interface for ...
/**
 */
qclass Foo [arg=QoreFoo* foo; ns=Foo];

//! Constructor
/** Used by subclasses defined in Qore
 */
Foo::constructor() {
    self->setPrivate(CID_FOO, new QoreFoo(self));
}

//! a method to ...
/**
 */
abstract nothing Foo::bar();

这允许类Foo拥有一些私有数据和一个抽象的Qore API,可以由子类使用;C++中的子类(用qpp实现)应该将Foo声明为vparent,如下例所示:

QoreFoo2.h

代码语言:javascript
复制
#include "qore/intern/QoreFoo.h"

class QoreFoo2 : public QoreFoo {
public:
     DLLLOCAL QoreFoo2(QoreObject* o) : QoreFoo(o) {
     }

     DLLLOCAL void bar(ExceptionSink* xsink) {
         printf("Hello World from C++");
     }

     // other functions...
};

QC_Foo2.qpp

代码语言:javascript
复制
#include "qore/intern/QoreFoo2.h"

//! This class ...
/**
 */
qclass Foo2 [arg=QoreFoo2* foo; ns=Foo; vparent=Foo];

//! Constructor
/** Used by subclasses defined in the Qore programming language.
 */
Foo2::constructor() {
    self->setPrivate(CID_FOO2, new QoreFoo2(self));
}

//! a method to ...
/**
 */
nothing Foo2::bar() {
    foo->bar();
}

此外,Foo类也可以在Qore中以相同的方式直接子类:

代码语言:javascript
复制
class Foo3 inherits Foo {
    bar() {
        print("Hello world from Q");
    }
}

编辑

@TMa如果您想要从C++调用Qore语言方法,那么就像前面提到的那样使用QoreObject::evalMethodValue() -您是正确的,qpp不为您生成此代码。

如果要确保该方法是在继承父类的任何Qore语言类中实现的,那么请确保在qpp文件中定义定义父类的抽象Qore方法。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42307205

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档