我有一个头文件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
答案 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 为我解决了。