Qt(C ++):函数的多个定义

时间:2015-11-02 23:58:19

标签: c++ qt

我有一个头文件header.h,其中包含我的所有类,与之关联的函数以及补充头文件(<QDebug><QString>等等)。唯一使用header.h的文件是我的主窗口mainwindow.h。但是,对于header.h中的每个函数,Qt Creator中出现的错误如下所示(其中in_cards::use_card()是示例函数):

 In function `ZN8in_cards8use_card()`               [moc_mainwindow.o]
 multiple definition of `in_cards::use_card()`      [header.h]          258
 first defined here                                 [header.h]          258

我已经按照其他问题的建议检查了.pro文件,并没有重复.cpp,.h或.ui文件。

任何建议或朝着正确方向迈出的一步都将受到赞赏。

编辑:以下是两个头文件的内容。

header.h

#ifndef HEADER_H
#define HEADER_H

#include <QDebug>
#include <QIntValidator>
#include <QItemDelegate>
#include <QLineEdit>
#include <QString>
#include <QStringList>
#include <QTextEdit>
#include <QVector>
#include <QWidget>

// - - - - - C P U  C L A S S - - - - -
class cpu
{
    private:
        int ac;
        int ir;
        int pc;

    public:
        // C O N S T R U C T O R S
        cpu() :
            ac (0),
            ir (0),
            pc (0) { }

        // D E S T R U C T O R S
        ~cpu() { }

        // G E T T E R S
        int get_ac() const { return ac; }
        int get_ir() const { return ir; }
        int get_pc() const { return pc; }

        // S E T T E R S
        bool set_ac(int a);
        bool set_ir(int i);
        bool set_pc(int p);

        // P R I N T E R S
        QString print_ac();
        QString print_ir();
        QString print_pc();

        // O T H E R
        bool increment_pc();
};

// S E T T E R S

bool cpu::set_ac(int a)
{
    if(a >= -999 && a <= 999)
    {
        ac = a;
        return true;
    }

    return false;
}

bool cpu::set_ir(int i)
{
   if(i >= 0 && i <= 999)
   {
       ir = i;
       return true;
   }

   return false;
}

bool cpu::set_pc(int p)
{
    if(p >= 0 && p <= 99)
    {
        pc = p;
        return true;
    }

    return false;
}

// P R I N T E R S
QString cpu::print_ac()
{
    QString print;
    int     a = ac;

    if(a < 0)
    {
        a = a * -1;
        print = "-";
    }

    if(a <= 9)
    {
        print = print + "00" + (QString::number(a));
    }
    else if(a <= 99)
    {
        print = print + "0" + (QString::number(a));
    }
    else if(a <= 999)
    {
        print = print + (QString::number(a));
    }
    else
    {
        print = "err";
    }

    return print;
}

QString cpu::print_ir()
{
    QString print;
    int     i = ir;

    if(i <= 9)
    {
        print = "00" + (QString::number(i));
    }
    else if(i <= 99)
    {
        print = "0" + (QString::number(i));
    }
    else if(i <= 999)
    {
        print = (QString::number(i));
    }
    else
    {
        print = "err";
    }

    return print;
}

QString cpu::print_pc()
{
    QString print;
    int     p = pc;

    if(p <= 9)
    {
        print = "0" + (QString::number(p));
    }
    else if(p <= 99)
    {
        print = (QString::number(p));
    }
    else
    {
        print = "err";
    }

    return print;
}

// O T H E R

bool cpu::increment_pc()
{
    if(pc != 99)
    {
        pc++;
        return true;
    }

    return false;
}

// - - - - - I N P U T  C A R D  C L A S S - - - - -
struct in_card
{
    int  value;
    bool used;
    bool empty;

    void set_value(int v)  { value = v; }
    void set_used (bool u) { used  = u; }
    void set_empty(bool e) { empty = e; }
};

class in_cards
{
    private:
        QVector<in_card> cards;

    public:
        // C O N S T R U C T O R S
        in_cards();

        // D E S T R U C T O R S
        ~in_cards() { }

        // S E T T E R S
        void set_card(int loc,
                      int val);

        // C H E C K E R S
        bool card_available();

        // G E T T E R S
        int use_card();
        QVector<int>     get_as_ints   ();
        QVector<QString> get_as_strings();


};

// C O N S T R U C T O R S
in_cards::in_cards()
{
    for(int i = 0; i < 15; i++)
    {
        in_card new_card;

        new_card.value = 1000;
        new_card.used = false;
        new_card.empty = true;

        cards.push_back(new_card);
    }
}

// S E T T E R S

void in_cards::set_card(int loc, int val)
{
    cards[loc].set_value(val);
    cards[loc].set_used(false);
    cards[loc].set_empty(false);
}

// C H E C K E R S

bool in_cards::card_available()
{
    for(int i = 0; i < cards.size(); i++)
    {
        if(cards.at(i).used == false)
        {
            return true;
        }
    }

    return false;
}

// G E T T E R S

int in_cards::use_card()
{
    for(int i = 0; i < cards.size(); i++)
    {
        if(cards.at(i).used == false)
        {
            if(cards.at(i).empty == false)
            {
                cards[i].set_used(true);

                return cards.at(i).value;
            }
            else
            {
                return 1000;
            }
        }
    }
}

QVector<int> in_cards::get_as_ints()
{
    QVector<int> values;

    for(int i = 0; i < cards.size(); i++)
    {
        values.push_back(cards.at(i).value);
    }

    return values;
}

// - - - - - O U T P U T  C A R D  C L A S S - - - - -
class out_cards
{
    private:
        QVector<int> cards;

    public:
        // C O N S T R U C T O R S
        out_cards() { }

        // D E S T R U C T O R S
        ~out_cards() { }

        // S E T T E R S
        bool set_card(int c);

        // G E T T E R S
        QVector<int>     get_as_ints   () { return cards; }
        QVector<QString> get_as_strings();
};

// S E T T E R S

bool out_cards::set_card(int c)
{
    if(c >= -999 && c <= 999)
    {
        cards.push_back(c);

        return true;
    }

    return false;
}

// - - - - - M E M O R Y  C L A S S - - - - -
struct mem_cell
{
    int  value;
    bool empty;

    void set_value(int v) { value = v; }
    void set_empty(bool e) { empty = e; }
};

class memory
{
    private:
        QVector<mem_cell> cells;

    public:
        // C O N S T R U C T O R S
        memory();

        // D E S T R U C T O R S
        ~memory() { }

        // G E T T E R S
        int get_value_at(int v) const { return cells.at(v).value; }
        QVector<int> get_as_ints();
        bool get_empty_at(int e) const { return cells.at(e).empty; }

        // S E T T E R S
        void set_cell(int loc, int val) { cells[loc].set_value(val); cells[loc].set_empty(false); }
};

// C O N S T R U C T O R S
memory::memory()
{
    for(int i = 0; i < 100; i++)
    {
        mem_cell new_cell;

        new_cell.value = 1000;
        new_cell.empty = true;

        cells.push_back(new_cell);
    }
}

// G E T T E R S
QVector<int> memory::get_as_ints()
{
    QVector<int> values;

    for(int i = 0; i < 100; i++)
    {
        values.push_back(cells.at(i).value);
    }

    return values;
}

#endif

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "header.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);

    void format_all();

    void format_inputTable();

    void format_outputTable();

    void setup_run();

    ~MainWindow();

private slots:

    void on_runButton_clicked();

    void on_clearInputButton_clicked();

    void on_clearOutputButton_clicked();

    void on_clearAllButton_clicked();

private:
    Ui::MainWindow *ui;

    cpu the_cpu;
    in_cards the_in_cards;
    out_cards the_out_cards;
    memory the_memory;
};

#endif

3 个答案:

答案 0 :(得分:1)

对于项目中的每个标题,请执行以下操作: 假设您的标题名为myheader

#ifndef MYHEADER_H
#define MYHEADER_H

//your declerations go here
#endif

溶液:

头文件只不过是一个''text''文件。 preproccessor将只复制粘贴您的标题代码。在标头中声明函数,在.cpp文件中定义它们。更改代码并从声明中分离定义,代码将编译。

答案 1 :(得分:0)

尽管在很多情况下将实现分成源文件是一个好主意,但是仅标头的库也是一种常见的方法。那么,这里出了什么问题?

导致此问题的最接近的原因是,虽然仅包含一次header.h(或者只写了一个来源< / em>文件#include通过mainwindow.h对其进行了保存),它又被moc从您的mainwindow.h构建的源文件中包含了(因此moc_mainwindow.o在错误消息中)。

如果您的header.h仅使用一次就可以使用,但要做的正确超越标头后卫可以防止出现问题一个转换单元多次包含相同的标头)是用来声明您的函数inline。关键字不必出现在每个函数上:对于函数模板(或类模板的成员函数)而言是不必要的,并且在类定义内定义了成员函数时就隐含了这个含义。

答案 2 :(得分:0)

我也收到此错误,但原因不同。

执行 qmake 为我解决了。