我需要在QoreFoo中实现C++类,并通过.qpp实现Qore脚本Foo的双重实现。QoreFoo是提供通用API的抽象类,实际功能将在子类和类中添加(在C++或Qore中)。来自核心i.e.C++的Foo调用需要传播到实例化对象,而不管在何处使用子类。
QoreFoo.h
# 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
QoreFoo* current_foo = 0;any.cpp
if (current_foo)
current_foo.bar(xsink); // propagate call via overriden method当我需要实现C++后代时,这是微不足道的:
QoreFoo2.h
class QoreFoo2: QoreFoo {
void bar(ExceptionSink *xsink) {
# my stuff
printf("Hello World from C++");
}
};usage.cpp
QoreAssignFoo(new QoreFoo2);
# wait for "Hello World from C++" when core calls current_foo.bar()
.....但是如何将调用传播到Qore脚本类?我认为需要额外的类来调用.qpp中定义的对偶类和.q中的overriden类。
QoreFooHelper.h
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
# 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
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来实现它(在将一般对象作为参数传递时存在额外的问题)。
发布于 2017-02-17 22:10:52
如果要执行的API是Qore语言类API,则需要在Qore而不是C++中实现抽象类。
如果您有一个应该在Qore中扩展的C++虚拟类层次结构,那么您应该使用qpp在C++中实现您的Qore类,然后允许程序员通过在Qore中子类来自然地扩展它。
你可以这样做:
QoreFoo.h
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
//! 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
#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
#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中以相同的方式直接子类:
class Foo3 inherits Foo {
bar() {
print("Hello world from Q");
}
}编辑
@TMa如果您想要从C++调用Qore语言方法,那么就像前面提到的那样使用QoreObject::evalMethodValue() -您是正确的,qpp不为您生成此代码。
如果要确保该方法是在继承父类的任何Qore语言类中实现的,那么请确保在qpp文件中定义定义父类的抽象Qore方法。
https://stackoverflow.com/questions/42307205
复制相似问题