如何在此处获取"已定义"的链接器错误?

tec*_*ble 1 c++

我是第一次尝试用C++进行单元测试,多年来我没有使用过C++(目前我主要是C#编码器).看起来我正在做一个正确的猪耳朵 - 我希望有人能引导我回到正义的道路上.我刚开始在这里开始,并且真的希望使用最佳实践来实现这些测试,所以欢迎任何和所有评论,即使我目前最关心的是我的链接器错误.

所以,我有一个整体解决方案"Technorabble",子项目"CalibrationTool"和"CalibrationToolUnitTests".

CalibrationTool有一个MathUtils.h文件:

#ifndef __math_utils__
#define __math_utils__

#include "stdafx.h"
#include <vector>

namespace Technorabble
{
    namespace CalibrationTool
    {
        double GetDoubleVectorAverage(std::vector<double> v)
        {
            double cumulativeValue = 0;
            for(std::vector<double>::iterator iter = v.begin(); iter != v.end(); ++iter) 
            {
                cumulativeValue += *iter;
            }
            return cumulativeValue / v.size();
        }
    }; // end namespace CalibrationTool
};  // end namespace Technorabble

#endif // !__math_utils__
Run Code Online (Sandbox Code Playgroud)

(但是没有.cpp文件,因为我有各种(有些类似的)问题让我的模板功能正常工作 - 所以我最终定义了内联).

继续单元测试项目,我有一个main.cpp:

#include "MathUtilsTest.h"

void RunMathUtilsTests();

int main()
{
    RunMathUtilsTests();

    // Other class tests will go here when I have things to test
}

void RunMathUtilsTests()
{
    MathUtilsTest* mathUtilsTest = new MathUtilsTest();
    mathUtilsTest->RunTests();
    delete mathUtilsTest;
}
Run Code Online (Sandbox Code Playgroud)

最后,MathUtilsTest类的头和cpp再次相当简单:

.H:

#ifndef __MATH_UTILS_TEST__
#define __MATH_UTILS_TEST__

#include "CalibrationToolUnitTestsLogging.h"
#include "..\CalibrationTool\MathUtils.h"

class MathUtilsTest
{
public:
    MathUtilsTest();
    ~MathUtilsTest();

     bool RunTests();

private:    
    bool GetDoubleVectorAverageTest();

}; // end class MathUtilsTest

#endif
Run Code Online (Sandbox Code Playgroud)

的.cpp:

#include "MathUtilsTest.h"
#include <sstream>

bool MathUtilsTest::RunTests()
{
    return GetDoubleVectorAverageTest();

}

MathUtilsTest::~MathUtilsTest()
{

}

MathUtilsTest::MathUtilsTest()
{

}

bool MathUtilsTest::GetDoubleVectorAverageTest()
{
    bool passed = true;
    std::vector<double> values;
    for (int i = 1; i < 23; i++)
    {
        values.push_back(i);
    }
    // vector becomes: 1, 2, 3, 4, .....20, 21, 22.  Average is 11.5
    double expectedAverage = 11.5;
    double calculatedAverage = Technorabble::CalibrationTool::GetDoubleVectorAverage(values);
    if (calculatedAverage != expectedAverage)
    {
        std::ostringstream s;
        s << calculatedAverage;
        std::string avgString = s.str();
        CalibrationToolUnitTestsLogging::Write("Failed MathUtilsTest.GetDoubleVectorAverageTest:  " + avgString);
        passed = false;
    }
    else
    {
        CalibrationToolUnitTestsLogging::Write("Passed MathUtilsTest.GetDoubleVectorAverageTest");
    }

    return passed;
}
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎很好,我用#ifndef等保护我的标题但是我仍然遇到以下错误:

1)错误LNK1169:找到一个或多个多重定义的符号

2)错误LNK2005:"double __cdecl Technorabble :: CalibrationTool :: GetDoubleVectorAverage(class std :: vector>)"(?GetDoubleVectorAverage @ CalibrationTool @ Technorabble @@ YANV?$ vector @ NV?$ allocator @ N @ std @@@ std @@@ Z)已在main.obj中定义C:_SVN\Technorabble\Windows Software\CalibrationToolUnitTests\MathUtilsTest.obj

怎么会这样?任何人都可以发现它出错的地方吗?

Luc*_*ore 5

标题中定义的函数应标记为inline:

inline double GetDoubleVectorAverage(std::vector<double> v)
{
}
Run Code Online (Sandbox Code Playgroud)

如果它比两行长,请考虑将其移动到实现文件.

pragmas或包含警卫不能防止多种定义.

请注意,您应该传递v通过const引用而不是通过值.