2

我收到此错误,但我不明白,因为从未在 DisplayErrorMessage.cpp 中声明“int const ITEMS”,就像它在下面的错误中所说的那样......任何帮助。

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 "自动售货机.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);
}

显示错误消息.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;
}

帮助普利兹。

4

3 回答 3

5

你的问题

extern int const ITEMS = 9;

标记这extern是正确的,但是你继续给它一个定义,取消了所有可爱的正确性。

当您在标题中定义符号时,无论您是否使用包含防护当您的翻译单元链接在一起时,您都会遇到多个定义错误。

您必须在一个ITEMS翻译单元中精确定义符号——这通常意味着在“源”文件中定义它,而不是在标题中。


天真的修复

所以,在你的标题中:

extern int const ITEMS;  // definition found elsewhere

然后,在一个.cpp 文件中:

int const ITEMS = 9;

真正的修复

但是,哎呀!您需要在标题中使用此常量,因为某些数组大小依赖于它。

ITEMS因此,您不必在程序中的所有翻译单元之间共享一个符号,而是必须对每个翻译单元都有一个本地定义。为此,我们使用static关键字将符号文件设为静态。

所以,在你的标题中:

static int const ITEMS = 9;  // visible only in this TU

现在,多个翻译单元(松散ITEMS说,这意味着static每个使用此标头的 .cpp)将有自己的版本因此它们不会在链接时发生冲突。

于 2013-08-20T15:15:11.517 回答
5

首先,在您的标题中Vending Machine.h(顺便说一句,在文件名中包含空格是个坏主意,为什么不直接命名它VendingMachine.h呢?),以下行:

  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

于 2013-08-20T15:18:47.157 回答
3
  extern int const ITEMS = 9;

由于您包含初始化程序,因此此声明也是一个定义。既然你声明了它extern,就只有一个对象ITEMS。但是有了头文件中的那一行,包含头文件的所有内容都有自己的定义。

您可以省略extern,在这种情况下,const将暗示static

  int const ITEMS = 9;

然后ITEMS是每个编译单元中的不同对象,但是如果您始终将其用作值并且从不对其地址做任何事情,那并不重要。

或者,如果您启用了 C++11 支持,您可以:

  constexpr int ITEMS = 9;

...它告诉编译器将一个ITEMS对象视为一个inline函数,并且可以多次定义它。

于 2013-08-20T15:21:16.200 回答