代码之家  ›  专栏  ›  技术社区  ›  Francisco José Letterio

链接器说,如果我试图在另一个文件(运行测试)中定义某个函数,则该函数已被定义

  •  1
  • Francisco José Letterio  · 技术社区  · 3 年前

    测验cpp:

    #include "pch.h"
    #include "CppUnitTest.h"
    #include <iostream>
    #include "PrintOne.cpp"
    
    using namespace Microsoft::VisualStudio::CppUnitTestFramework;
    
    namespace PointandVectorCreationTest
    {
        TEST_CLASS(PointandVectorCreationTest)
        {
        public:
            
            TEST_METHOD(TestMethod1)
            {
                std::string expected = "1\n";
    
                std::stringstream buffer;
                std::streambuf* sbuf = std::cout.rdbuf(); // Save cout's buffer
                std::cout.rdbuf(buffer.rdbuf()); // Redirect cout to the stringstream buffer
    
                int result = printOne();
    
                // When finished, redirect cout to the original buffer 
                std::cout.rdbuf(sbuf);
                std::cout << "std original buffer: \n";
                std::cout << buffer.get();
    
                // Test
                Assert::AreEqual(expected, buffer.str());
            }
        };
    }
    

    普林通。cpp:

    #include <iostream>
    
    int printOne() {
        std::cout << 1 << std::endl;
        return 0;
    }
    

    当我尝试在Visual Studio中运行此测试时,链接器抛出以下错误:

    Test.obj .

    printOne 在任何地方 Test.cpp 测验cpp 并消除 PrintOne.cpp

    测验cpp:

    #include "pch.h"
    #include "CppUnitTest.h"
    #include <iostream>
    
    int printOne() {
        std::cout << 1 << std::endl;
        return 0;
    }
    
    using namespace Microsoft::VisualStudio::CppUnitTestFramework;
    
    namespace PointandVectorCreationTest
    {
        TEST_CLASS(PointandVectorCreationTest)
        {
        public:
            
            TEST_METHOD(TestMethod1)
            {
                std::string expected = "1\n";
    
                std::stringstream buffer;
                std::streambuf* sbuf = std::cout.rdbuf(); // Save cout's buffer
                std::cout.rdbuf(buffer.rdbuf()); // Redirect cout to the stringstream buffer
    
                int result = printOne();
    
                // When finished, redirect cout to the original buffer 
                std::cout.rdbuf(sbuf);
                std::cout << "std original buffer: \n";
                std::cout << buffer.get();
    
                // Test
                Assert::AreEqual(expected, buffer.str());
            }
        };
    }
    

    测试运行得很好。我宁愿避免将我使用的所有函数都写在我测试它们的同一个文件中,所以对我来说,这不应该是一个解决方案。

    2 回复  |  直到 3 年前
        1
  •  2
  •   Remy Lebeau    3 年前

    我没有定义 printOne Test.cpp .

    #include 的源代码 PrintOne.cpp 进入 . 如果您随后编译并链接这两个 测验cpp 普林通。cpp 总之,链接器确实可以看到 printOne() .obj 文件

    .h 宣布 printOne() #包括 这两个文件都有 .cpp 文件,其中只有一个 定义 ,例如:

    #include "pch.h"
    #include "CppUnitTest.h"
    #include <iostream>
    #include "PrintOne.h"
    
    using namespace Microsoft::VisualStudio::CppUnitTestFramework;
    
    namespace PointandVectorCreationTest
    {
        TEST_CLASS(PointandVectorCreationTest)
        {
        public:
            
            TEST_METHOD(TestMethod1)
            {
                std::string expected = "1\n";
    
                std::stringstream buffer;
                std::streambuf* sbuf = std::cout.rdbuf(); // Save cout's buffer
                std::cout.rdbuf(buffer.rdbuf()); // Redirect cout to the stringstream buffer
    
                int result = printOne();
    
                // When finished, redirect cout to the original buffer 
                std::cout.rdbuf(sbuf);
                std::cout << "std original buffer: \n";
                std::cout << buffer.get();
    
                // Test
                Assert::AreEqual(expected, buffer.str());
            }
        };
    }
    

    普林通。H

    #pragma once
    int printOne();
    

    #include "PrintOne.h"
    #include <iostream>
    
    int printOne() {
        std::cout << 1 << std::endl;
        return 0;
    }
    
        2
  •  1
  •   Adrian Mole Chris    3 年前

    当你有一行像 #include "PrintOne.cpp" Test.cpp PrintOne.cpp (包括 printOne() 测验cpp 的源代码;因此 Test.obj 文件将包含 printOne() 作用

    如果你也有 项目中包含的文件-从链接器引用 PrintOne.obj 模块-然后会有 而且 printOne() 函数也在该对象文件中。

    因此,您有多个(尽管相同)函数定义,这是链接器发出的信号。

    普林通。cpp 用一个文件作为标题(例如 #include "PrintOne.h" 公告 printOne 函数(如果源文件是项目的一部分,则将添加源文件的内容。)

    一般来说,不建议 #include ... 源(cpp)文件(尽管有 一些 When do I need to #include .cpp files?