链接错误2019,原型虽然在头文件中

时间:2014-04-09 00:21:07

标签: c++ lnk2019 unresolved-external

我是c +的新手,只是想尝试一个涉及3个文件的问题。

我有一个带有命名空间的头文件,声明了一个结构和一些原型。在definitions.cpp文件中,我有所有的函数定义。然后main.cpp文件,只创建一些结构,调用一些函数来填充结构,然后调用另一个函数来显示结构。

我遇到的问题是它给了我一个未解决的外部错误。根据我的收集,我认为编译器抱怨它无法找到main.cpp中调用的函数的原型 - 重载的setStruct()showStruct()

但我想当我包含header.h文件并使用using声明声明函数时,在main.cpp中,它让编译器访问存储在头文件中的原型?

Header.h

#ifndef header_h
#define header_h

namespace SALES
{
    const int QUARTERS = 4;

    struct Sales
    {
        double sales[QUARTERS];
        double average;
        double max;
        double min;
    };
    void setSales(Sales & s, const double ar[], int n);
    void setSales(Sales & s);
    void showSales(const Sales & s);
}

#endif

Definitions.cpp

#include<iostream>
#include"header.h"
using SALES::Sales;
using SALES::QUARTERS;


double max(Sales & s) //find max sale value in sales array
{
    double maxVal = s.sales[0];
    for(int i = 1; i<4;i++)
    {
        if(s.sales[i]>maxVal)
        {
            maxVal = s.sales[i];  
        }

    }
    return maxVal;
}

double min(Sales & s) //find min sale value in sales array
{
    double minVal = s.sales[0];
    for(int i = 1; i<4;i++)
    {
        if(s.sales[i]<minVal)
        {
            minVal = s.sales[i];  
        }

    }
    return minVal;
}

void setSales(Sales & s) // fill sales structure interactivly
{
    std::cout<< "Please enter the sales for the yearly quarters.\n";
    for(int i = 0;i<QUARTERS;i++)
    {
        std::cout<< "Quater "<<i+1<<": ";
        while(!(std::cin>>s.sales[i]))
        {
            std::cout<<"Please enter valid input\n";
            std::cout<< "Quater "<<i+1<<": ";
            std::cin.clear();
            std::cin.ignore();
        }

    }
    s.average = ((s.sales[0]+s.sales[1]+s.sales[2]+s.sales[3])/4); 
    s.max = max(s);
    s.min = min(s);

}


void setSales(Sales & s, const double ar[], int n) // fill sales structure non interactivly
{
    for(int i = 0;i<n;i++)
    {
        s.sales[i] = ar[i];
    }
    for(int i = n;i<QUARTERS;i++)
    {
        s.sales[i] = 0;
    }
    s.average = ((s.sales[0]+s.sales[1]+s.sales[2]+s.sales[3])/4); 
    s.max = max(s);
    s.min = min(s);


}

void showSales(const Sales & s) // display structure
{
    std::cout<< "\nSales for the year\n";
    for(int i = 0;i<QUARTERS;i++)
    {
        std::cout<<"Quarter "<<i+1<<": $"<<s.sales[i];
    }
    std::cout<<"Max Sale: "<<s.max<<std::endl;
    std::cout<<"Min Sale: "<<s.min<<std::endl;
    std::cout<<"Average of sales: "<<s.average<<std::endl;
}

Main.cpp的

#include<iostream>
#include"header.h"

using SALES::Sales;
using SALES::setSales;
using SALES::showSales;

int main()
{
    double Sales1[4] = {453.50, 654.60, 340.20, 500.30};

    Sales Year1;
    Sales Year2;

    setSales(Year1, Sales1, 3);
    setSales(Year2);

    showSales(Year1);
    showSales(Year2);

    return 0;
}

错误

1>------ Build started: Project: Myfirst, Configuration: Debug Win32 ------
1>  Main.cpp
1>Main.obj : error LNK2019: unresolved external symbol "void __cdecl SALES::setSales(struct SALES::Sales &,double const * const,int)" (?setSales@SALES@@YAXAAUSales@1@QBNH@Z) referenced in function _main
1>Main.obj : error LNK2019: unresolved external symbol "void __cdecl SALES::setSales(struct SALES::Sales &)" (?setSales@SALES@@YAXAAUSales@1@@Z) referenced in function _main
1>Main.obj : error LNK2019: unresolved external symbol "void __cdecl SALES::showSales(struct SALES::Sales const &)" (?showSales@SALES@@YAXABUSales@1@@Z) referenced in function _main
1>E:\Documents\Uni\Programming\C++ starter projects\Myfirst\Debug\Myfirst.exe : fatal error LNK1120: 3 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

任何帮助都会很棒,谢谢。

2 个答案:

答案 0 :(得分:1)

定义setSales etc函数时,需要告诉编译器它们在SALES命名空间中。把

namespace SALES
{

    // functions here
}

会这样做。

答案 1 :(得分:0)

您目前正在任何名称空间之外定义您的函数,这就是链接器无法在名称空间中找到声明和识别这些函数的定义的原因。

修复方法是将函数包装在实现文件中 - Definitions.cpp - ,与命名空间类似,如何在头文件中执行此操作。

如果我是你,我会写这个:

namespace SALES
{
    ...
    void setSales(Sales & s) // fill sales structure interactivly
    ...
        std::cout<<"Average of sales: "<<s.average<<std::endl;
    }
}

如果你没有将其余的(你的最小值和最大值)放入命名空间,请使用::范围说明符以防万一,尽管我建议将所有内容放入你自己的命名空间。