gpt4 book ai didi

c++ - 错误 : forward declaration of ‘class SActionPrivate’ when using PIMPL

转载 作者:行者123 更新时间:2023-11-30 03:58:03 27 4
gpt4 key购买 nike

在Qt程序中我实现了Pimpl方法,有3个文件

saction.cpp

saction.h

saction_p.h - with a private class sactionPrivate

该代码基于 kdelibs 中的代码。我正在使用 CMAKE 作为构建系统。所以编译的时候报错

build/moc_saction.cpp:73:22: 错误:无效使用不完整类型‘class SActionPrivate’actions/saction.h:492:18: 错误:‘类 SActionPrivate’ 的前向声明

问题出在文件moc_saction.cpp,它不包含文件saction_p.h,只包含saction.h

所以我需要在生成的 moc 文件中手动添加行:

#include "../actions/saction_p.h"

我应该怎么做,才能不手动更正 moc 文件???

CMakeLists.txt

project(scalc)
cmake_minimum_required(VERSION 2.6)
find_package(Qt4 REQUIRED)

include_directories(
${QT_INCLUDES}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/actions
)

set(scalc_SRCS

actions/saction.cpp

main.cpp )

set(CMAKE_AUTOMOC ON)

add_executable(scalc ${scalc_SRCS} )

target_link_libraries(scalc ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})
install(TARGETS scalc RUNTIME DESTINATION bin)

actions/saction.h

#ifndef SACTION_H
#define SACTION_H

#include <QtGui/QWidgetAction>

class SAction : public QWidgetAction
{
Q_OBJECT
public:
explicit SAction(QObject *parent);
virtual ~SAction();

private:
friend class SActionPrivate;
class SActionPrivate* const d;
Q_PRIVATE_SLOT(d, void slotTriggered())
};


#endif

actions/saction_p.h

#ifndef SACTION_P_H
#define SACTION_P_H

class SAction;


class SActionPrivate
{
public:

SActionPrivate():q(0)
{
}

void slotTriggered();

void init(SAction *q_ptr);

SAction *q;

};

#endif

actions/saction.cpp

#include "saction.h"
#include "saction_p.h"

#include <QtGui/QApplication>
#include <QtGui/QHBoxLayout>
#include <QtGui/QShortcutEvent>
#include <QtGui/QToolBar>

void SActionPrivate::init(SAction *q_ptr)
{
q = q_ptr;

QObject::connect(q, SIGNAL(triggered(bool)), q, SLOT(slotTriggered()));

q->setProperty("isShortcutConfigurable", true);
}


void SActionPrivate::slotTriggered()
{}

SAction::SAction(QObject *parent)
: QWidgetAction(parent), d(new SActionPrivate)
{
d->init(this);
}

SAction::~SAction()
{
delete d;
}

main.cpp

#include "saction.h"

int main(int argc, char** argv)
{
SAction gg(new QWidget());
}

由cmake moc_saction.cpp生成

#include "../actions/saction.h"
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'kaction.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 63
#error "This file was generated using the moc from 4.8.6. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif

QT_BEGIN_MOC_NAMESPACE
static const uint qt_meta_data_SAction[] = {

// content:
6, // revision
0, // classname
0, 0, // classinfo
1, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount

// slots: signature, parameters, type, tag, flags
9, 8, 8, 8, 0x08,

0 // eod
};

static const char qt_meta_stringdata_SAction[] = {
"SAction\0\0slotTriggered()\0"
};

void SAction::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
SAction *_t = static_cast<SAction *>(_o);
switch (_id) {
case 0: _t->d->slotTriggered(); break;
default: ;
}
}
Q_UNUSED(_a);
}

const QMetaObjectExtraData SAction::staticMetaObjectExtraData = {
0, qt_static_metacall
};

const QMetaObject SAction::staticMetaObject = {
{ &QWidgetAction::staticMetaObject, qt_meta_stringdata_SAction,
qt_meta_data_SAction, &staticMetaObjectExtraData }
};

#ifdef Q_NO_DATA_RELOCATION
const QMetaObject &SAction::getStaticMetaObject() { return staticMetaObject; }
#endif //Q_NO_DATA_RELOCATION

const QMetaObject *SAction::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
}

void *SAction::qt_metacast(const char *_clname)
{
if (!_clname) return 0;
if (!strcmp(_clname, qt_meta_stringdata_SAction))
return static_cast<void*>(const_cast< SAction*>(this));
return QWidgetAction::qt_metacast(_clname);
}

int SAction::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QWidgetAction::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 1)
qt_static_metacall(this, _c, _id, _a);
_id -= 1;
}
return _id;
}
QT_END_MOC_NAMESPACE

最佳答案

对了,这里有两个问题:

  • 缺少生成 moc 的 cmake 二进制目录的包含路径

    ${CMAKE_CURRENT_BINARY_DIR}
  • 您需要在相应源文件的末尾包含 moc 文件

    #include "moc_saction.cpp"

关于c++ - 错误 : forward declaration of ‘class SActionPrivate’ when using PIMPL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27626977/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com