gpt4 book ai didi

C++:通过简单的添加示例了解头文件和头文件保护

转载 作者:行者123 更新时间:2023-11-30 00:51:31 27 4
gpt4 key购买 nike

我无法理解头球和头球后卫。我已经阅读了其他问题及其答案,但我仍然无法在 Visual Studio 2013 中完成这项工作:

main.cpp

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

int _tmain(int argc, _TCHAR* argv[]) {
std::cout << "3 + 4 = " << add(3, 4) << std::endl;
system("pause");
return 0;
}

add.cpp

#include "stdafx.h" //ADDED LATER; NOW WORKING (AND SEE QUESTION 2 BELOW)
#include "add.h" //ADDED LATER; NOR WORKING (AND SEE QUESTION 2 BELOW)
int add(int x, int y) {
return x + y;
}

add.h

#ifndef ADD_H
#define ADD_H
int add(int x, int y);
#endif

当我编译时,控制台窗口在屏幕上闪烁然后消失。错误列表包含:

Error 1 error LNK2019: unresolved external symbol "int __cdecl add(int,int)" (?add@@YAHHH@Z) referenced in function _wmain c:\Users\Danny\documents\visual studio 2013\Projects\Addition Program\main\main.obj main

Error 2 error LNK1120: 1 unresolved externals c:\users\danny\documents\visual studio 2013\Projects\Addition Program\Debug\main.exe main


1。 header 和 header 防护装置如何工作?我通过#including add.h 了解如何, 它使 main.cpp了解 add(int x, int y) 的声明, 那么它是如何找到它的定义的呢?


2。我的代码有什么问题?

我的代码现在正在编译。我的代码没有编译的原因是因为我一直在使用 File > New > File... 将文件添加到我的项目中,而不是通过 Source Files Solution Explorer 的 strong> 和 Header Files 部分。我还需要添加 #include "stdafx.h添加到 add.cpp 文件。

最佳答案

这样想:每个 .cpp 文件都经过预处理,然后完全独立于其他文件进行编译。

所以让我们首先预处理main.cpp。这涉及查看所有以 # 开头的行。 main.cpp 文件只有 #include 行,它们只是复制它们包含的文件的内容。我将用注释表示 stdafx.hiostream 的内容,但实际上我会复制 add.h 的内容> 在:

// Contents of stdafx.h
// Contents of iostream
#ifndef ADD_H
#define ADD_H
int add(int x, int y);
#endif

int _tmain(int argc, _TCHAR* argv[]) {
std::cout << "3 + 4 = " << add(3, 4) << std::endl;
system("pause");
return 0;
}

现在看到add.h的内容已经被引入main.cpp了吗?碰巧这带来了更多的预处理器指令,所以我们需要按照他们说的去做。第一个检查 ADD_H 是否还没有定义(在这个文件中),它没有,所以一切都留到 #endif:

// Contents of stdafx.h
// Contents of iostream
#define ADD_H
int add(int x, int y);

int _tmain(int argc, _TCHAR* argv[]) {
std::cout << "3 + 4 = " << add(3, 4) << std::endl;
system("pause");
return 0;
}

现在剩下的预处理器指令定义了 ADD_H,我们剩下最后的翻译单元:

// Contents of stdafx.h
// Contents of iostream
int add(int x, int y);

int _tmain(int argc, _TCHAR* argv[]) {
std::cout << "3 + 4 = " << add(3, 4) << std::endl;
system("pause");
return 0;
}

现在可以编译这个文件了。如果你调用像 add 这样的函数,编译器只需要能够看到该函数的声明就可以成功编译。预计该函数将在一些其他翻译单元中定义。

现在让我们看看预处理 add.cpp。事实上,add.cpp 没有任何预处理指令,因此不需要发生任何事情。通常,您会#include "add.h",但如果您不这样做,您的程序仍会编译。所以在预处理之后我们仍然有:

int add(int x, int y) {
return x + y;
}

然后编译,我们现在有了 add 函数的定义。

在编译所有 .cpp 文件后,它们将被链接。链接器负责查看编译后的 main.cpp 使用函数 add 并查找其定义。它在编译后的 add.cpp 中找到定义并将它们链接在一起。


然后您可能想知道为什么我们要包括守卫。在这个例子中它似乎毫无值(value)。没错,在这个例子中它并没有真正的用处。包含守卫可以防止同一个文件头在一个文件中被包含两次。当你有一个更复杂的项目结构时,这很容易发生。但是,让我们看一个不切实际的例子,其中 main.cpp 包含 add.h 两次:

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

int _tmain(int argc, _TCHAR* argv[]) {
std::cout << "3 + 4 = " << add(3, 4) << std::endl;
system("pause");
return 0;
}

预处理这给你:

// Contents of stdafx.h
// Contents of iostream
#ifndef ADD_H
#define ADD_H
int add(int x, int y);
#endif
#ifndef ADD_H
#define ADD_H
int add(int x, int y);
#endif

int _tmain(int argc, _TCHAR* argv[]) {
std::cout << "3 + 4 = " << add(3, 4) << std::endl;
system("pause");
return 0;
}

第一个 #ifndef 将被处理,它会看到 ADD_H 尚未定义,并且 #endif 之前的所有内容都会保持。然后定义 ADD_H

然后第二个#ifndef被处理了,但是此时ADD_H已经被定义了,所以直到#endif的一切都会被处理丢弃。

这非常重要,因为对一个函数(以及许多其他东西)进行多个定义会给您带来错误。

关于C++:通过简单的添加示例了解头文件和头文件保护,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21487896/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com