单继承方法时编译错误[Qt新手]

时间:2011-05-08 18:51:49

标签: c++ qt

我是PyQt程序员并且正在尝试学习C ++ Qt。

我正在关注this链接,了解如何导入我的ui文件。但是当我尝试编译时,我收到了这个错误:

[utdmr@utdmr-arch cpp]$ qmake -project && qmake && make
/usr/bin/uic ui.ui -o ui_ui.h
g++ -c -m64 -pipe -march=x86-64 -mtune=generic -O2 -pipe -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt/mkspecs/linux-g++-64 -I. -I/usr/include/QtCore -I/usr/include/QtGui -I/usr/include -I. -I. -I. -o main.o main.cpp
/usr/bin/moc -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt/mkspecs/linux-g++-64 -I. -I/usr/include/QtCore -I/usr/include/QtGui -I/usr/include -I. -I. -I. gui.h -o moc_gui.cpp
g++ -c -m64 -pipe -march=x86-64 -mtune=generic -O2 -pipe -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt/mkspecs/linux-g++-64 -I. -I/usr/include/QtCore -I/usr/include/QtGui -I/usr/include -I. -I. -I. -o moc_gui.o moc_gui.cpp
g++ -m64 -Wl,--hash-style=gnu -Wl,--as-needed -Wl,-O1 -o cpp main.o moc_gui.o    -L/usr/lib -lQtGui -lQtCore -lpthread 
moc_gui.o: In function `Gui::Gui(QWidget*)':
moc_gui.cpp:(.text+0x80): multiple definition of `Gui::Gui(QWidget*)'
main.o:main.cpp:(.text+0x0): first defined here
moc_gui.o: In function `Gui::Gui(QWidget*)':
moc_gui.cpp:(.text+0x80): multiple definition of `Gui::Gui(QWidget*)'
main.o:main.cpp:(.text+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [cpp] Error 1

但我在代码上看不到多重定义。我也是C ++类继承的新手。

这是我的档案:

gui.h:

#include "ui_ui.h"

class Gui : public QWidget
{
    Q_OBJECT

    public:
        Gui(QWidget *parent=0);
    private:
        Ui::Form ui;
};


Gui::Gui(QWidget *parent)
        : QWidget(parent)
{
          ui.setupUi(this);
}

main.cpp中:

#include <QApplication>
#include "gui.h"

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

    Gui gui;
    gui.show();

    return app.exec();
}

ui_ui.h:http://paste.kde.org/56251/(我使用了pastebin,因为它很长)

感谢。

2 个答案:

答案 0 :(得分:3)

您应该将函数定义放入.cpp文件中。 所以用以下内容创建gui.cpp:

#include "gui.h"

Gui::Gui(QWidget *parent)
        : QWidget(parent)
{
          ui.setupUi(this);
}

将其从.h文件中删除。

您收到错误的原因是头文件包含在多个.cpp文件中(您的main.cpp和moc_gui.cpp,一个生成的文件),因为函数定义在头文件中被多重定义。

哦,别忘了将新的.cpp文件添加到项目中。如果您忘记了,您将收到有关未定义函数的链接错误!

@ cbamber85对你原来的问题做了一些很好的评论。虽然在这种情况下你的问题不是由于你的项目变得越来越大而没有多个包含守卫造成的,但你可能遇到问题所以现在养成习惯会很有用。要保护您的文件gui.h免受多重包含,请执行以下操作:

#ifndef GUI_H_
#define GUI_H_

#include "ui_ui.h"

class Gui : public QWidget
{
    Q_OBJECT

    public:
        Gui(QWidget *parent=0);
    private:
        Ui::Form ui;
};

#endif

实际的宏名称GUI_H_并不重要,您可以使用SnOOpy但是您需要为每个头文件使用不同的宏名称,因此使用文件名的某些变体是常见做法。通常只在#define d宏中使用大写字母(只是一个约定;编译器不关心)。

在许多现代编译器中,您可以简单地使用:

#pragma once

#include "ui_ui.h"

class Gui : public QWidget
{
    Q_OBJECT

    public:
        Gui(QWidget *parent=0);
    private:
        Ui::Form ui;
};

好的,那么多重包含是什么?何时发生?好吧,假设你有一个名为types.h的文件,它定义了你经常使用的一些基本类型。现在假设你有两个类Foo和Bar,每个类都使用types.h中的类型。这可能是这样的:

文件:types.h

typedef int Int32;

文件:foo.h

#include "types.h"
class Foo
{ 
    Int32 mCount;
};

档案:bar.h

#include "types.h"
class Bar
{
    Int32 mLength;
};

注意我遗漏了多个包含警卫。现在假设我有一个使用Foo和Bar的main:

#include "foo.h"
#include "bar.h"

int main(int argc, const char* argv[])
{
    Foo f;
    Bar b;
    return 0;
}

如果没有多个包含警卫,这将会抱怨Int32被多重定义......问题是什么?好吧,因为main.cpp包含foo.h,而foo.h包含types.h,它包含在那里,然后当包含bar.h时,它还包含types.h,因此它包含 second 时间那里。

我希望这一切都有道理。我故意将它从原来的答案中删除,但根据评论,解释它可能更好。

答案 1 :(得分:1)

这部分:

Gui::Gui(QWidget *parent)
    : QWidget(parent)
{
      ui.setupUi(this);
}

需要进入.cpp文件。否则,它将包含在包含该标头的所有目标文件中。 (您可以将其放在main.cpp中以开始使用,但将它放在单独的gui.cpp中会更常见。)