致命错误乘以定义的符号

时间:2013-08-20 14:45:48

标签: c++

我收到此错误但我不明白,因为“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。

3 个答案:

答案 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/3994572https://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函数类似,并且可以多次定义。