已在main.obj中定义了双精度

Double already defined in main.obj

本文关键字:双精度 定义 main obj 已在      更新时间:2023-10-16

我目前遇到了一个问题。它要求打印某种商店库存管理的月度销售额,然后要求用户输入1-12之间的数字,以查看特定月份的总销售额。

我必须向您提供我在Visual Studio中完成此操作后所拥有的内容(创建了一个空白/空项目,因此没有"stdafx.h"文件。它应该在那里吗?):

销售.h:

#pragma once
#ifndef DEPTS
#define DEPTS 2
#endif
#ifndef STORES
#define STORES 2
#endif
#ifndef MONTHS
#define MONTHS 12
#endif
using namespace std;
double storeMonthlySales[STORES][MONTHS][DEPTS] = {
{
{1.1, 1.2}, {1.3, 1.4}, {1.5, 1.6}, {1.7, 1.8}, {1.9, 2.0}, {2.1, 2.2},
{2.1, 2.2}, {2.3, 2.4}, {2.5, 2.6}, {2.7, 2.8}, {2.9, 3.0}, {3.1, 3.2}
},
{
{3.1, 3.2}, {3.3, 3.4}, {3.5, 3.6}, {3.7, 3.8}, {3.9, 4.0}, {4.1, 4.2},
{2.1, 2.2}, {2.3, 2.4}, {2.5, 2.6}, {2.7, 2.8}, {2.9, 3.0}, {3.1, 3.2}
}
};
void printMonthlySales(double ss[DEPTS][MONTHS][STORES], int mon);

销售.cpp:

#include "Sales.h"
#include <iostream>
using namespace std;
void printMonthlySales(double ss[DEPTS][MONTHS][STORES], int mon)
{
if ((mon < 1) || (mon > MONTHS))
{
cout << "nMonth must be a number (1 = January, through 12 = December). Try again. n" << endl;
}
else
{
double store_total = 0;
double dept_total = 0;
double total = 0;
cout << "tt";
for (int h = 0; h < DEPTS; h++)
{
cout << "Department " << h + 1 << "tt";
}
cout << "Store Total" << endl;
for (int i = 0; i < STORES; i++)
{
cout << "Store " << i << "tt";
for (int j = 0; j < DEPTS; j++)
{
double d = ss[j][mon][i];
cout << d << "tt";
store_total += d;
total += d;
}
cout << endl;
}
cout << "Department Totalt";
for (int i = 0; i < DEPTS; i++)
{
for (int j = 0; j < STORES; j++)
{
double d = ss[j][mon][i];
cout << d << "tt";
}
}
cout << total << "tt" << endl;
}
}

到目前为止,这就是我对main.cpp的了解。目前还不完整,但我只是在确保我走在正确的轨道上:

main.cpp:

#include "Sales.h"
#include <algorithm>
#include <iostream>
#include <sstream>
using namespace std;
int main(void)
{
printMonthlySales(storeMonthlySales, 1);
string a;
cin >> a;
return 0;
}

因此,到目前为止,我应该打印MonhtlySales商店的MonthlySales第1个月(1月)。"string a"answers"cin>>a"只是为了防止终端窗口自动关闭(同样,我在Visual Studio中这样做)。

然而,我正在编译这些文件,我得到了两个错误:

LNK2005 "double (* storeMonthlySales)[12][2]" (?storeMonthlySales@@3PAY1M@1NA) already defined in main.obj
LNK1169 one or more multiply defined symbols found

我很困惑为什么他们说MonthlySales这个印刷品"已经定义好了",因为我在这里没有看到任何错误。查看Sales.obj和main.obj文件没有任何结果。

当您包含一个文件时,它会被有效地复制并粘贴到包含文件中。标头中的所有内容现在都是正在编译的文件的一部分。#pragma once和其他形式的包含保护防止文件在翻译单元中被包含不止一次。

但是。。。

翻译单位是单独编制的,因此它们之间没有连续性。B.cpp无法知道A.cpp已经包含了一个给定的头。事实上,想想如果一个大型项目中只有一个文件可以#include <string>,情况会有多糟糕。C++甚至还没走出办公室,进入贝尔实验室的走廊,就已经被当作浪费时间而丢弃了。

所以。。。A.cpp和B.cpp都包含header.h。它们都有自己的header.h中所有内容的副本。两者都编译得很好,但链接器不知道如何处理相互竞争的定义。

解决方案:

销售中。h:

extern double storeMonthlySales[STORES][MONTHS][DEPTS];

extern承诺将在某个地方定义storeMonthlySales,以便编译器可以继续执行其工作。如果没有定义,链接器将抱怨。

在Sales.cpp中:

double storeMonthlySales[STORES][MONTHS][DEPTS] = {
{
{1.1, 1.2}, {1.3, 1.4}, {1.5, 1.6}, {1.7, 1.8}, {1.9, 2.0}, {2.1, 2.2},
{2.1, 2.2}, {2.3, 2.4}, {2.5, 2.6}, {2.7, 2.8}, {2.9, 3.0}, {3.1, 3.2}
},
{
{3.1, 3.2}, {3.3, 3.4}, {3.5, 3.6}, {3.7, 3.8}, {3.9, 4.0}, {4.1, 4.2},
{2.1, 2.2}, {2.3, 2.4}, {2.5, 2.6}, {2.7, 2.8}, {2.9, 3.0}, {3.1, 3.2}
}
};

这就是定义。它只存在于Sales.cpp中。任何包含Sales.h 的文件都可以使用它

顺便说一句,小心using namespace std;。这会给你带来麻烦。

因为你把storeMonthlySales的定义放在了Sales.h中,所以每当有东西包括Sales.h时,它就会被重新定义。在你的情况下,这种情况会发生两次——一次在Sales.cpp中,另一次在main.cpp中。一个常见的误解是#pragma once(和标头保护)会阻止这种情况——他们不会。它们防止多次包含关联的.cpp文件,但不会包含.h本身。因此,解决方案是将您的storeMonthlySales定义移动到Sales.cpp.