首页 文章

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

提问于
浏览
1

我有一个头文件 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

2 回答

  • 1

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

    #ifndef MYHEADER_H
    #define MYHEADER_H
    
    //your declerations go here
    #endif
    

    解:

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

  • 0

    虽然在许多情况下将实现分离到源文件是个好主意,但是仅标头库也是一种常见的方法 . 那么这里出了什么问题?

    问题的原因在于,虽然您可能只包含了一次 header.h (或者更确切地说,只通过 mainwindow.h 只写了一个源文件 #include ),但 mainwindow.h 构造的源文件再次包含它 mainwindow.h 错误消息中的 moc_mainwindow.o ) .

    虽然 header.h 如果真的只使用过一次就会起作用,但 correct 要做的事情(除了防止一个翻译单元多次包含相同 Headers 时出现问题的 Headers 保护)就是声明你的函数 inline . 关键字不需要出现在每个函数上:它不需要函数模板(或类模板的成员函数),并且在类定义中定义成员函数时隐含 .

相关问题