繁体   English   中英

main.cpp怎么看?

[英]How does main.cpp see this?

刚开始是用C ++编写的,所以有点菜鸟,不知道为什么会这样。 main.cpp如何看待使用单独的print.cpp文件中包含的print()函数? 我以为您必须使用#include / header文件或类似的文件? 如果有帮助,我正在使用Visual Studio。

main.cpp

#include "stdafx.h"
#include <iostream>
#include <string>

void print(std::string message);

int main()
{
    std::cout << "Enter message: ";
    std::string message = "";
    std::getline(std::cin, message);
    print(message);
    return 0;
}

print.cpp

#include "stdafx.h"
#include <iostream>
#include <string>

void print(std::string message)
{
    std::cout << "Your message is - " << message << std::endl;
}

实际上,main.cpp 的代码根本无法“看到” print.cppprint功能

编译器根据您先前在文件中编写的不完整函数规范(而不是来自其他文件的任何内容)检查对print的调用。 C ++允许使用这种不完整的规范作为一种说法,“好吧,我现在不告诉您如何实现此功能,但是在编译了该文件和所有其他文件并准备好链接在一起之后,应该可以使用它。一些现有的库。”

您提到了包含文件。 include指令所做的全部工作是(除其他事项外)直接在程序内部放置一堆局部函数规范。 包含之后(在编译器运行之前作为预处理阶段运行),您将拥有一些类似于上面的main.cpp的代码。 实际上,对于C ++编译器,您的代码看起来与用不规范的print函数规范替换为包含该规范的文件的#include指令的代码看上去没有什么不同。

关于编写不完整的函数规范的一个有趣的事情是,实现这些规范的函数通常可以用不同的语言编写,只要它们的数据类型直接映射到C ++类型即可。 在您的情况下, std::string将您直接绑定到C ++,但是如果您使用int甚至char*使用汇编语言或C语言的外部程序,则可以使用!

可以在单独的翻译单元中编译代码的原因是链接 :链接是名称的属性,名称具有三种链接,这些链接决定了在不同范围内看到名称时的含义:

  • 无:没有链接的名称的含义对于该名称出现的范围是唯一的。 例如,“正常”的变量的函数内声明没有联动,所以名字ifoo()具有从所述名称的不同意义ibar()

  • 内部的:具有内部链接的名称的含义在每个翻译单元内是相同的,但在翻译单元之间是不同的。 一个典型的例子是在名称空间范围内声明的变量名称,这些变量是常量,或出现在未命名的名称空间中,或使用static说明符。 举一个具体的例子, static int n = 10; 在一个.cpp文件中声明的名称在该文件内使用该名称的每次使用均指代同一实体,但在不同文件中使用不同的static int n指代不同的实体。

  • 外部:在整个程序中,具有外部链接的名称的含义相同。 也就是说,无论您在声明具有外部链接的特定名称时,该名称都指的是同一事物。 这是名称空间范围内函数和非常量函数的默认链接,但是您也可以显式请求与extern说明符的外部链接。 例如, extern int a; 将在程序中的任何地方引用相同的int对象。

现在,我们了解您的程序如何组合在一起(或:“链接”):名称print具有外部链接(因为它是函数的名称),因此程序中的每个声明都引用相同的函数。 在main.cpp中有一个用于调用该函数的声明,而在print.cpp中还有一个用于定义该函数的声明,这两个含义相同。这意味着您在main调用的东西与您所调用的东西完全相同。在print.cpp中定义。

头文件的使用没有任何魔术:头文件只是在文本上被替换,现在我们精确地看到了什么头文件有用:它们对于保存具有外部链接的名称声明非常有用,以便任何想要引用的人因此,实体名称具有将这些声明包含在其代码中的简便且可维护的方式。

您可以完全不使用标题,但是这将要求您准确地知道如何声明所需的名称,这通常是不希望的,因为声明的细节由库所有者(而不是用户)拥有,并且图书馆所有者有责任维护和运送声明。

现在,您还将看到翻译工具链中“链接器”部分的目的是:链接器将对具有外部链接的名称的引用进行匹配。 链接器在第一个翻译单元中的print名称引用中使用已定义实体的最终地址,该实体的名称(来自第二个翻译单元)位于最终链接中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM