我收到此错误但我不明白,因为“int const ITEMS”从未在DisplayErrorMessage.cpp中声明,就像它在下面的错误中所说的那样。任何帮助。
1>Main.obj : error LNK2005: "int const ITEMS" (?ITEMS@@3HB) already defined in DisplayErrorMessage.obj
1>MakeSelection.obj : error LNK2005: "int const ITEMS" (?ITEMS@@3HB) already defined in DisplayErrorMessage.obj
1>ShowMenu.obj : error LNK2005: "int const ITEMS" (?ITEMS@@3HB) already defined in DisplayErrorMessage.obj
1>c:\users\kanaan\documents\visual studio 2010\Projects\Assign2\Debug\Assign2.exe : fatal error LNK1169: one or more multiply defined symbols found
以下是代码:
标头文件
#ifndef _VENDINGMACHINE_H_
#define _VENDINGMACHINE_H_
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
//extern int Denominations;
extern int const ITEMS = 9;
extern int Coins[5];
extern int NumCoins[5]; //assume we have 10 coins of each denomination
extern int ItemPrice[ITEMS ]; //price in cents
extern int NumItems[ITEMS];
//extern double Total_Price;
//extern double Item_Total;
class VendingMachine{
public:
void MakeSelection();
int ReturnChange(int change, int Coins[], int NumCoins[]);
void ShowMenu();
void DisplayErrorMessage(int error);
void PrintConfidentialInformation(int Denominations, int Items, int Coins[],
int NumCoins[], int ItemPrice[] , int NumItems[]);
private:
int selection;
string code;
double Each_Item[ITEMS]; //price for each item
};
#endif //_VENDING_MACHINE_H_
cpp文件如下。 MakeSelection.cpp #include“Vending Machine.h”
void VendingMachine::MakeSelection(){
//assume we have 10 coins of each denomination
double Total_Price;
// double Item_Total;
int Coins[5] = {100, 50, 20, 10, 5};
int NumCoins[5] = {10, 10, 10, 10, 10};
int ItemPrice[ITEMS] = { 75, 120, 120, 100, 150, 95, 110, 50, 120 }; //price in cents
int NumItems[ ITEMS] = { 10, 10, 10, 10, 10, 10, 10, 10, 10 };
string Product[ITEMS] = {"Water","Coke","Diet Coke","Iced Tea","Swiss Chocolate","Candy",
"Chips","Bubble Gum","Turkish Delight"};
int b = 0;
int a = 1;
cout << "Please enter the number of your choice from the menu above. " << endl;
do{
cout << "\nEnter the number of product OR End transaction: " << endl;
cin >> selection;
cout << "\nYou have selected " <<Product[selection] << endl;
if(selection >= 1 && selection <= 9){
NumItems[selection - 1] = NumItems[selection - 1] - 1;
if(NumItems[selection - 1] >= 0)
Total_Price = Total_Price + ItemPrice[selection - 1];
else{
int error = 1;
DisplayErrorMessage(error); //Item finised
cout <<selection<< endl;
}
}
else if(selection == 10)
cout << "\nTransaction Ended" << endl;
else if(selection == 99){
cout << "Enter the code to access maintanance: " <<endl;
cin >> code;
while(code != "111"){
int error = 2;
DisplayErrorMessage(error);
cin >> code;
}
cout << endl;
cout << "\t\t\t\t\tSales Report " << endl;
cout << "==================================================== " << endl;
cout << endl;
cout << "Number of each product sold with Income cost: " << endl;
cout << endl;
do{
if(NumItems[b] >= 0){
Each_Item[b] = Each_Item[b] + ItemPrice[b];
cout << NumItems[b] << "" << Product[b] << " sold for the total cost of " <<(10 - NumItems [b]) * Each_Item[b]/ 100 <<endl;
Total_Price = Total_Price + ((10 - NumItems[b]) * Each_Item[b]/100);
}
b++;
}while(a <= ITEMS);
}
else{
int error = 3;
DisplayErrorMessage(error);
}
}while(selection != 10);
}
DisplayErrorMessage.cpp
#include "Vending Machine.h"
void VendingMachine::DisplayErrorMessage(int error){
if (error == 1){
cout << "\nSorry we are run out of item number ";
}
else if (error == 2){
cout << "\nInvalid selection - Please re-select your choice" << endl;
}
else if (error == 3){
cout << "\nIncorrect Password - Please re-enter" << endl;
}
else
cout << "\nNot enough fund" << endl;
}
帮助PLIZ。
答案 0 :(得分:5)
extern int const ITEMS = 9;
标记此extern
是正确的,但随后你继续给它一个定义,取消所有可爱的正确性。
当您在标题中定义符号时,无论您是否使用包含警示而不是,当翻译单元链接在一起时,您将收到多个定义错误。
您必须在精确的一个翻译单元中定义符号ITEMS
- 这通常意味着在“源”文件中定义它,不标题。< / p>
所以,在你的标题中:
extern int const ITEMS; // definition found elsewhere
然后,在一个 .cpp文件中:
int const ITEMS = 9;
但是, oops!你的标题中需要这个常量,因为某些数组大小依赖它。
因此,您不必在程序中的所有翻译单元之间共享一个符号ITEMS
,而是必须在每个翻译单元的本地定义。为此,我们使用static
关键字使符号文件成为静态。
所以,在你的标题中:
static int const ITEMS = 9; // visible only in this TU
现在,多个翻译单元(松散地说,这意味着使用此标头的每个.cpp)将拥有自己的ITEMS
版本,就像之前一样......但这一次,因为它们被标记为{ {1}},每个本地到该翻译单元,因此它们不会在链接时发生冲突。
答案 1 :(得分:5)
首先,在标题Vending Machine.h
中(顺便说一句,在文件名中包含空格是个坏主意,为什么不将它命名为VendingMachine.h
?),如下所示:< / p>
extern int const ITEMS = 9;
是定义,而不是声明,尽管extern
,因为初始化部分(“= 9
”)。
现在,此标头包含多个来源(.cpp
)文件,ITEMS
有外部链接(明确因为extern
),导致每个源文件(重新)定义相同的 ITEMS
,因此会出现多重定义错误。
如果您将行更改为
static int const ITEMS = 9;
或只是
int const ITEMS = 9;
(由于const
全局变量的特定规则实际上是等效的),然后每个ITEMS
(在每个源文件中)将具有内部链接,这将是一切都很好。
编辑此外,以下答案很好地解释了extern
的两个含义(“外部链接”和“声明,未定义”):https://stackoverflow.com/a/2840401
修改:关于extern
的两个其他好答案(添加了“静态存储时长”的含义):https://stackoverflow.com/a/3994572和https://stackoverflow.com/a/18450398
答案 2 :(得分:3)
extern int const ITEMS = 9;
由于您包含初始值设定项,因此该声明也是一个定义。由于您声明它为extern
,因此只有一个对象ITEMS
。但是在头文件中的那一行,包含头部的所有内容都有自己的定义。
您可以不使用extern
,在这种情况下const
将隐含static
。
int const ITEMS = 9;
然后ITEMS
在每个编译单元中都是一个不同的对象,但如果你总是将它用作一个值,那么这并不重要,并且永远不会对它的地址做任何事情。
或者,如果您启用了C ++ 11支持,则可以:
constexpr int ITEMS = 9;
...告诉编译器将ITEMS
对象视为与inline
函数类似,并且可以多次定义。