我有一个类,其成员变量指向库对象。
class myClassA {
private:
libraryClass *libraryObject;
}
库类发出以字符串为特征的事件,并提供一种机制,允许客户端类指定在发出事件时应调用的成员函数,因此在 myClassA 中,我可以做到
libraryObject->connect ("eventName", this, &myClassA::privateMember);
我现在希望 myClassA 的客户能够将其成员函数连接到事件,方法是将公共成员函数 connect 添加到 myClassA < / em>的。我应该如何在 myClassA 头文件中声明 connect ?
具体来说,我正在使用Qt并尝试允许客户端( myClassA )调用 QScxmlStateMachine :: connectToEvent 。此函数的Qt documentation将其描述为
QMetaObject::Connection QScxmlStateMachine::connectToEvent(
const QString &scxmlEventSpec,
const QObject *receiver,
PointerToMemberFunction method,
Qt::ConnectionType type = Qt::AutoConnection)
但我不清楚应该如何定义 PointerToMemberFunction 。
Qt头文件将其声明为
template <typename Func1>
QMetaObject::Connection connectToEvent(
const QString &scxmlEventSpec,
const typename QtPrivate::FunctionPointer<Func1>::Object *receiver, Func1 slot,
Qt::ConnectionType type = Qt::AutoConnection);
而不是我只是盲目地将其复制到我的代码中并查看它是否有效,请有人向我解释这个声明;特别是我读到它说有些东西是模板化的,我不明白是什么,为什么我不需要做任何模板-y来使用这个机制。
感谢。
答案 0 :(得分:2)
QtPrivate::FunctionPointer
是一种类型特征模板,可以帮助新的Qt信号/插槽语法。
How Qt Signals and Slots Work - Part 2 - Qt5 New Syntax
类型特征:
QtPrivate::FunctionPointer
特征基本上是一个辅助类,它提供有关给定元数据的元数据 类型。 Qt中另一个特征的例子是
QTypeInfo
。为了实现新语法,我们需要知道的是 有关函数指针的信息。
template<typename T> struct FunctionPointer
会给我们 有关T
通过其成员的信息。
ArgumentCount
:一个整数,表示函数的参数个数。
Object
:仅存在指向成员函数的指针。它是函数所属类的typedef。
Arguments
:表示参数列表。它是元编程列表的typedef。
call(T &function, QObject *receiver, void **args)
:一个静态函数,它将调用函数,应用给定的参数。...
FunctionPointer
的实施位于qobjectdefs_impl.h。
此特征允许根据提供的参数选择正确的QScxmlStateMachine::connectToEvent
- QObject
槽,仿函数或函数指针(包含或不包含上下文)。
// connect state to a QObject slot
template <typename Func1>
inline QMetaObject::Connection connectToEvent(
const QString &scxmlEventSpec,
const typename QtPrivate::FunctionPointer<Func1>::Object *receiver, Func1 slot,
Qt::ConnectionType type = Qt::AutoConnection)
// connect state to a functor or function pointer (without context)
template <typename Func1>
inline typename QtPrivate::QEnableIf<
!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction &&
!std::is_same<const char*, Func1>::value, QMetaObject::Connection>::Type
connectToEvent(const QString &scxmlEventSpec, Func1 slot,
Qt::ConnectionType type = Qt::AutoConnection)
// connectToEvent to a functor or function pointer (with context)
template <typename Func1>
inline typename QtPrivate::QEnableIf<
!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction &&
!std::is_same<const char*, Func1>::value, QMetaObject::Connection>::Type
connectToEvent(const QString &scxmlEventSpec, QObject *context, Func1 slot, Qt::ConnectionType type = Qt::AutoConnection)
因此,如果您需要允许所有情况,您可以使用相同的原型提供方法并转发参数。
答案 1 :(得分:2)
完成所有各种包含文件,同时制定问题可以解决此问题。
我在 myClassA
的头文件中包含以下内容template <typename Func1> // Lifted from QtScxmlStateMachine.h
QMetaObject::Connection connectToEvent(
const QString &scxmlEventSpec,
const typename QtPrivate::FunctionPointer<Func1>::Object *receiver, Func1 slot,
Qt::ConnectionType type = Qt::AutoConnection) {
return libraryObject->connectToEvent(scxmlEventSpec, receiver, slot, type);
};
myClassA 的客户端现在可以调用 myClassA :: connectToEvent 来调用基础 QtScxmlStateMachine 的 connectToEvent member。
谢谢你,StackOverflow,强迫我按顺序正确地理解我的想法。