我目前正在使用C ++进行项目。 简而言之,我有3个类和一个main.cpp文件。
1)列表类//使用向量 2)堆类 3)树类// BST
为了正确地组织自己,我将每个类分成单独的文件,即.hpp和.cpp文件。
当然要访问main.cpp文件中每个类的所有功能,我#include了所有三个.hpp文件。
一切工作始终保持一致,直到我将“ List.hpp”文件包含在“ heap.hpp”和“ Tree.hpp”中。
奇怪的是,当我仅将“ List.hpp”包含在单个单独的头文件(例如“ heap.hpp”)中时,没有出现错误。
但是当我由于某种原因将#List.hpp包含在这两种方法中时,过去有效的方法不再起作用。
仅依赖于“列表”作为参数的方法不再起作用(它们什么也不返回)。
我确定不是为什么会这样。这是第二次发生在我身上,我想知道为什么会这样,所以我不会在以后犯错。
答案 0 :(得分:2)
简单规则:
所有文件,无论是* .cpp还是* .h文件,都应独立存在,应包括编译该文件本身所需的所有其他头文件。
如果* .h文件需要一个定义,则来自另一个* .h文件,因此您应该直接在此处添加它。
如果不这样做,则必须处理从第三个文件包含头文件的正确顺序,这可能会令人沮丧。
但是随着项目的增长,您将常常不再使用包含甚至不包含所有必需依赖项但编译良好的文件,因为之前包含的其他文件已经包含了您所需的内容。
有一个助手来管理这些事情: include what you use
还有一个基本的用法:使用诸如#pragma once
之类的守卫或旧式#ifndef XYZ #define XYZ #endif
答案 1 :(得分:1)
在头文件中,请使用前向声明,而不要包括头,并将其包括在源文件中,除非您有充分的理由将其包括在头文件中。
答案 2 :(得分:0)
首先,扩展名无关紧要。包含文件可以是hpp
,h
或其他任何文件,甚至cpp
也可以。预处理程序查看#include指令和您指示的文件。尽管h
和hpp
是要使用的约定,所以请不要包括cpp文件。
现在,为了理解编译器的工作原理,每个#include指令都意味着该文件后面的内容已被完全处理。相当于将整个文件的内容粘贴到c / cpp文件中。
现在想象一下该文件的编译器将处理多少,尤其是如果您的其他包含文件中包含#includes时。
使用前向声明是您在大多数包含中发现的一种做法,如果希望避免代码冲突,则应首选使用。话虽这么说,仍然有一些情况需要避免前向声明,因为如果通过链接的库或其他对象来构建代码段,则可能会降低性能。但这通常仅在非常简单的函数被频繁调用时出现,编译器将能够内联函数->优化。
请记住这一点。