是否可以告诉脱交通部,我谨声明的类而实现它在一个单一文件而不是分裂它们成。h。cpp的文件?

有帮助吗?

解决方案 4

我相信这是最好的方式。它实际上是我现在该怎么构建我的所有对象。

Qt的4.8.7

Works.pro:

SOURCES += \
    main.cpp

HEADERS += \
    Window.h \
    MyWidget.h

的main.cpp

#include <QtGui>
#include "Window.h"

int main(int argc, char *argv[])
{
    QApplication app(argc,argv);

    Window window;
    window.show();
    return app.exec();
}

window.h中

#ifndef WINDOW_H
#define WINDOW_H

#include <QtGui>
#include "MyWidget.h"

class Window : public QWidget
{
    Q_OBJECT

private:
    MyWidget *whatever;

public:
    Window()
    {
        QHBoxLayout *layout = new QHBoxLayout;
        setLayout(layout);

        whatever = new MyWidget("Screw You");
        layout->addWidget(whatever);

    }
};

#include "moc_Window.cpp"

#endif // WINDOW_H

MyWidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QtGui>

class MyWidget : public QLabel
{
    Q_OBJECT

public:
    MyWidget(QString text) : QLabel(text)
    {
        // Whatever
    }
};

#include "moc_MyWidget.cpp"

#endif // MYWIDGET_H

...生成 的qmake Works.pro

其他提示

如果你想声明和实现你的cpp文件一个QObject子类,则必须手动包括商务部的文件。

例如:(文件main.cpp中)

struct SubObject : QObject
{
    Q_OBJECT
};

//...

#include "main.moc"

您有添加make qmake语句后重新运行的moc(#include)。

TL博士

是的,如果你只讨论的文件的编写自己(而不是那些由交通部).你不需要做什么特别的东西。

如果你曾经希望,包括交通部出明确的文件中,你写信,还有一个情况下在其中 必须 做到这一点,一种情况下你 可能会 希望这样做。让我们假设 MyObject 类声明 MyObject.h 和你的定义,它给予在 MyObject.cpp:

  1. MyObject.moc 必须 包括 在结束MyObject.cpp 森林论坛 你的任何声明 Q_OBJECT 课程内 MyObject.cpp.

  2. moc_MyObject.cpp 包括 任何地方MyObject.cpp 数减少一半的翻译单位在项目中。这是一个建立时优化只。如果你不这样做, moc_MyObject.cpp 将单独编制。

每次你添加或删除 Q_OBJECT 宏从任何来源头或文件,或者添加或删除的明确的内含物的交通部出在这些文件,必须重新运行qmake/cmake.

重新运行qmake/cmake在建造物主,只是右击顶级项目,并选择 运行qmake运行cmake 从上下文的菜单。

简单的回答

一个例子qmake基建项目可能包括的三个文件,具体如下:

# test.pro
QT       += core
CONFIG   += console
CONFIG   -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
HEADERS += myobject.h

// main.cpp
#include "myobject.h"

int main() {
  MyObject obj;
  obj.staticMetaObject; // refer to a value defined in moc output
  return 0;
}

// myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <QObject>

class MyObject : public QObject {
   Q_OBJECT
public:
   MyObject() {}
   Q_SLOT void aSlot() {}
};

#endif // MYOBJECT_H

它没有做多,但它肯定是有效的。除了各图书馆的建立系统的链接我们的项目,有两个具体项目 翻译单位: main.cppmoc_myobject.cpp.

即使它似乎整个执行情况 MyObject 在该标题的文件,它实际上不是。的 Q_OBJECT 宏宣称,某些位的实施,这将是不确定的,如果不是因为商务部所产生定义。

如何交通部进入画面?项目时首先建立,metabuild工具的任qmake或cmake-扫描的所有C++输入文件的存在 Q_OBJECT 宏。那些包含有它,给予特殊治疗。在这个例子项目, myobject.h 包含 Q_OBJECT 而是处理通过交通部成 moc_myobject.cpp.后者是列入名单的来源,汇编C++编译器。它是,只有在概念上,因为如果你不得不 SOURCES += moc_myobject.cpp.pro 文件。 你当然应该永远不会添加这样一个线的.亲的文件。

现在注意到 整个 执行情况 MyObject 掌握在两个文件: myobject.hmoc_myobject.cpp. myobject.h 可以包含尽可能多的翻译单位,如你所愿-因为没有出类(独立的)定义中,将违反这一定义的规则。在建立系统的对待 moc_myobject.cpp 作为一个单一的、单独的翻译单元--这是所有的照顾你。

因此你的目标是达到与没有在所有的努力:你有没有什么特别的事情要把整个执行情况 MyObject -保存的位部产生-进入该标题的文件。它可能延长的编制时间,但否则是无害的。

一规则的违反的方法

它违反了 一个定义的规则, 确切的说,是的,因而产生无效C++的程序。

现在你可能想要获得"聪明"和强制性地包括交通部出入标题的文件。该qmake/cmake/比斯将被收容,并将检测到这一点,并不会单独处理交通部的输出通过编译了,因为你已经做到了。

因此,假设,在该项目上所述,改变了你 myobject.h 如下:

// myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <QObject>

class MyObject : public QObject {
   Q_OBJECT
public:
   MyObject() {}
   Q_SLOT void aSlot() {}
};

#include "moc_myobject.cpp"
#endif // MYOBJECT_H

因为它的立场,该项目仍将汇编,似乎履行了你的目标具有的只是一个文件,该文件定义的整体的 MyObject -比特,你写道,这位部生成的,两者。但它仅仅由于一个不太可能幸福的情况下:的内容 moc_*.cpp 仍然在只有一个翻译单位

假设现在,我们增加一个第二个来源文件到我们的项目:

# test.pro
QT       += core
CONFIG   += console
CONFIG   -= app_bundle
TEMPLATE = app
SOURCES += main.cpp test.cpp
HEADERS += myobject.h

// test.cpp
#include "myobject.h"

不多。它应工作,甚至如果它没有做多了,对吗?

可惜的是,它不会的链接。现在的内容 moc_myobject.cpp 一部分的两个翻译单位。由于 moc_myobject.cpp's的内心是完全的独立类成员的定义,这违反了 一个定义的规则.该规则规定,独立的定义可能只出现在 一个翻译单位 在一目标。连接,被监护人的这条规则,正确地抱怨。

在包括交通部出的。cpp文件

正如TL博士,没有上述的排除了明确包含商业产出的来源(.cpp)的文件,在具体情况。

给予"foo。h"和"foo.cpp"和项目管理的qmake或cmake,建立系统将直接 moc 产生了两个产出:

  1. moc_foo.cppfoo.h, 森林论坛 foo.h 包含 Q_OBJECT 宏。

  2. foo.mocfoo.cpp, 森林论坛 foo.cpp 包含 #include "foo.moc".

让我们仔细研究为什么你想要包括两个中的一个。cpp文件。

包括xxx.交通部

有时候,特别是在前几天C++11和脱5,它涉及便利的声明的小助手QObject类为地方内使用一个翻译单元(资料来源文件)。

这也是方便的时候写的单一文件,自包含的测试案例和实例对计算器的使用。

假设你希望有人来证明,在一个文件,如何调用一个插槽从事件循环:

// main.cpp
#include <QCoreApplication>
#include <QTextStream>
#include <cstdio>

QTextStream out(stdout);

class MyObject : public QObject {
  Q_OBJECT
public:
  MyObject() {}
  Q_SLOT void mySlot() { out << "Hello from " << __FUNCTION__ << endl; }
};

int main(int argc, char ** argv) {
  QCoreApplication app(argc, argv);
  MyObject obj;
  QMetaObject::invokeMethod(&obj, Qt::QueuedConnection, "mySlot");
  QMetaObject::invokeMethod(&app, Qt::QueuedConnection, "quit");
  return app.exec();
}

#include "main.moc"

由于 MyObject 是一个小类,只使用本地 main.moc, 它不会有多大意义,把它定义为一个单独的标题的文件。的 #include "main.moc" 行将注意到通过qmake/cmake, main.cpp 将通过交通部,导致 main.moc.由于 main.moc 限定成员 MyObject, 它必须包括地方在哪里 MyObject 是的声明。作为《宣言》是在 main.cpp, 你不能拥有 main.moc 是一个单独的翻译单位:它不会由于汇编 MyObject 是不申报。唯一的地方,它是宣布紧 main.cpp, 某个地方。这就是为什么它是一个安全的赌注总是包括 foo.moc 在结束 foo.cpp.

一个精明的读者现在要求:怎么来的 moc_foo.cpp 获取的声明的类成员,它定义了?很简单:它明确地包括对标题的文件,它是产生(这里: foo.h).当然 foo.moc 不能做到这一点,因为它会破坏一个单一的定义规则,由乘限定的一切 foo.cpp.

包括moc_xxx.cpp

在特别的大型建项目,可能必须在平均水平的两个文件 两个翻译单位的每个类别:

  • MyObject.hMyObject.cpp 是的文件的编写。
  • MyObject.cppmoc_MyObject.cpp 是的翻译单位。

它是可能的数减少一半的翻译单位的明确包括 moc_MyObject.cpp 在某个地方 MyObject.cpp:

// MyObject.cpp
#include "MyObject.h"
#include "moc_MyObject.cpp"
...

我觉得你可以正常申报并实施的头文件中的类,而无需使用任何特殊,例如:

#include <QObject>

class MyClass : public QObject
{
  Q_OBJECT

  public:
     MyClass(QObject * parent)
     {
        // Constructor Content
     }

     methodExample()
     {
          // Method content
     }
};

在此,你的头文件添加到PRI文件,然后再执行qmake的,就是这样。你有一个类从Qobject继承并实现和诠释,他宣称.h文件中。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top