链接器错误与Qt信号/插槽示例

Kir*_*ril 5 c++ qt linker-errors visual-studio-2010

我有一个Qt应用程序,有多个类使用信号和插槽,它编译得很好.但是,当我在主CPP(main.cpp)文件中创建自定义类时,我收到链接器错误.

这是我使用的代码:

class Counter : public QObject
{
    Q_OBJECT

public:
    Counter() { m_value = 0; }

    int value() const { return m_value; }

public slots:
    void setValue(int value)
    {
     if(value!=m_value)
     {
         m_value = value;
         qDebug() << "Value " << value;
         emit valueChanged(value);
     }
    }

signals:
    void valueChanged(int newValue);

private:
    int m_value;
};

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    Counter a, b;
    QObject::connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int)));

    a.setValue(12);     // a.value() == 12, b.value() == 12
    b.setValue(48);     // a.value() == 12, b.value() == 48

    QTimer::singleShot(0, &app, SLOT(quit()));

    return app.exec();
}
Run Code Online (Sandbox Code Playgroud)

以下是错误:

Error   4   error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall Counter::metaObject(void)const " (?metaObject@Counter@@UBEPBUQMetaObject@@XZ)  
Error   5   error LNK2001: unresolved external symbol "public: virtual void * __thiscall Counter::qt_metacast(char const *)" (?qt_metacast@Counter@@UAEPAXPBD@Z)
Error   6   error LNK2001: unresolved external symbol "public: virtual int __thiscall Counter::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@Counter@@UAEHW4Call@QMetaObject@@HPAPAX@Z)   
Error   7   error LNK2019: unresolved external symbol "protected: void __thiscall Counter::valueChanged(int)" (?valueChanged@Counter@@IAEXH@Z) referenced in function "public: void __thiscall Counter::setValue(int)" (?setValue@Counter@@QAEXH@Z)
Run Code Online (Sandbox Code Playgroud)

将计数器放在单独的头文件中时,不会发生此链接器错误.这种行为的原因是什么?

Syn*_*xis 5

我假设你正在和我一起工作qmake.

moc由对头文件默认自动运行,因为这是类一般声明.请注意,此规则在makefile中定义,您可以moc在源文件上手动运行.

您必须通知qmake该文件包含一个类.要做到这一点,请#include "filename.moc"在声明之后Counter.您可以在此处查看更多详细信息(QtCentre)此处(doc).

如果你使用的是另一个工具而不是qmakeCMake,你必须指定一个规则来强制moc解析.cpp文件(最简单的是处理所有文件).对于不包含Qt对象类moc的文件,将生成一个空文件.

但是,即使将此类设置为"私有",我建议您在标题中声明它(例如counter_private.h).例如,Qt源正在使用这个技巧.