在main.obj中已经定义了Double

时间:2019-02-08 01:15:29

标签: c++ visual-c++

我当前是stuck on a problem.,它要求打印某种商店库存管理的月销售额,然后要求用户输入1-12之间的数字以查看特定月份的总数。

自从我在Visual Studio中进行此操作(创建一个空白/空项目,因此没有“ stdafx.h”文件。它应该存在吗?)之后,我将向您提供我所拥有的东西:

Sales.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);

Sales.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 << "\t\t";
        for (int h = 0; h < DEPTS; h++)
        {
            cout << "Department " << h + 1 << "\t\t";
        }
        cout << "Store Total" << endl;
        for (int i = 0; i < STORES; i++)
        {
            cout << "Store " << i << "\t\t";
            for (int j = 0; j < DEPTS; j++)
            {
                double d = ss[j][mon][i];
                cout << d << "\t\t";
                store_total += d;
                total += d;
            }
            cout << endl;
        }
        cout << "Department Total\t";
        for (int i = 0; i < DEPTS; i++)
        {
            for (int j = 0; j < STORES; j++)
            {
                double d = ss[j][mon][i];
                cout << d << "\t\t";
            }
        }
        cout << total << "\t\t" << 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;
}

因此,到目前为止,我应该为第1个月(1月)的storeMonhtlySales打印MonthlySales。刚好有“字符串a”和“ 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

我对他们为什么说printMonthlySales已经“定义”感到困惑,因为我在这里没有发现任何问题。浏览Sales.obj和main.obj文件无济于事。

2 个答案:

答案 0 :(得分:2)

包含文件时,文件将被有效复制并粘贴到包含文件中。头文件中的所有内容现在都属于要编译的文件的一部分。#pragma once,其他形式的包含保护可防止文件在translation unit中被多次包含。

但是...

翻译单元是单独编译的,因此它们之间没有连续性。 B.cpp无法知道A.cpp已包含给定的标头。实际上,请考虑一下,如果一个大项目中只有一个文件可以#include <string>,那将是多么糟糕的事情。 C ++甚至在离开办公室进入贝尔实验室的走廊之前都会被浪费时间。

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

解决方案:

在sales.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;。这会给您带来麻烦。

答案 1 :(得分:1)

由于您将storeMonthlySales的定义放在Sales.h中,因此每当包含Sales.h时它都会重新定义。在您的情况下,这种情况发生了两次-一次出现在Sales.cpp中,一次出现在main.cpp中。一个常见的误解是#pragma once(和标头保护符)将阻止这种情况,但事实并非如此。它们可以防止多次包括关联的.cpp文件,但不能保护.h本身。因此,解决方案是将storeMonthlySales定义移至Sales.cpp。

相关问题