【问题标题】:How does Visual Studio compile together multiple C++ files?Visual Studio 如何将多个 C++ 文件编译在一起?
【发布时间】:2020-11-10 03:13:32
【问题描述】:

我在 Visual Studio 中有一个简单的项目,使用 main.cppLog.cppLog.h

main.cpp:

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

int main()
{
    Log("Hello World");
    std::cin.get();
}

日志.cpp

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

void Log(std::string message)
{
    std::cout << message << std::endl;
}

void InitLog()
{
    Log("Initialized Logger");
}

Log.h:

#pragma once
#include <string>

void Log(std::string);
void InitLog();

我知道#include 语句将所有包含文件的代码复制粘贴到写入它的文件中。我的问题是,当我运行它时,函数 Log 是如何按预期运行的?

我们包含来自 main.cpp 和 Log.cpp 的 Log.h 文件,但这只是函数声明。我们从来没有在 main.cpp 中包含 Log.cpp,那么 main.cpp 是如何获取 Log() 的函数体的呢?

【问题讨论】:

  • Visual Studio IDE 还是 Visual Studio Code 编辑器?
  • Visual Studio IDE
  • 您只需将它们全部放入同一个构建项目中,它们应该会自动链接。
  • 虽然 this question 是关于 C 的,但同样的基本原则也适用:这是链接器所扮演的角色之一。它在翻译单元被编译为目标文件后解析外部引用,将其全部转换为单个可执行文件。
  • 从 C++ 风格的角度来看,这表明您应该有一个带有构造函数 (Log::Log) 和某种 log(const std::string&amp; message) 函数的 Log 类。注意const 引用的使用。这样可以避免复制可能会变得昂贵但几乎总是浪费的价值。

标签: c++ compilation linker include


【解决方案1】:

这被称为链接的过程。编译器需要知道Log 类中函数的返回类型和签名(这就是你包含头文件的原因),但如果它没有找到函数定义,它不会抛出错误。当它将 cpp 文件编译成目标代码文件时,它基本上会在函数定义应该去的地方留下“漏洞”。然后使用链接器将这些目标文件链接到一个可执行文件中。

但是,编译器确实需要知道类的数据成员,因为这些数据成员决定了对象占用的内存量,而这对于创建对象是必要的。同样,这些都包含在 main 中包含的头文件中的类定义中。

【讨论】:

    猜你喜欢
    • 2021-04-05
    • 2015-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多