C++ 需要为c+中的#includes++;库/标题设计不好的迹象?

C++ 需要为c+中的#includes++;库/标题设计不好的迹象?,c++,include,library-design,C++,Include,Library Design,我使用过一些非常大规模的系统,从未见过需要的订单,但最近遇到了它。STL或STD库甚至Boost是否存在某些包含必须以特定顺序出现的情况?这听起来绝对是个糟糕的设计。如果某种程度上需要特定的顺序,库应该提供一个标题,其中包含正确顺序的其他标题 至于boost和STL,我很确定我还没有遇到这种情况 STL或STD库甚至Boost是否存在某些包含必须以特定顺序出现的情况 我从未遇到过这种情况,如果是这样,那么必须尽快通知作者。哦,是的,这是一个非常糟糕的设计。如果头文件中包含的函数和/或类(比如,a

我使用过一些非常大规模的系统,从未见过需要的订单,但最近遇到了它。STL或STD库甚至Boost是否存在某些包含必须以特定顺序出现的情况?

这听起来绝对是个糟糕的设计。如果某种程度上需要特定的顺序,库应该提供一个标题,其中包含正确顺序的其他标题

至于boost和STL,我很确定我还没有遇到这种情况

STL或STD库甚至Boost是否存在某些包含必须以特定顺序出现的情况


我从未遇到过这种情况,如果是这样,那么必须尽快通知作者。哦,是的,这是一个非常糟糕的设计。

如果头文件中包含的函数和/或类(比如,a.h)依赖于另一个头文件(比如,B.h)中定义的函数和/或类,我更喜欢将后者包含在第一个头文件中,而不是强制第一个头文件的用户按特定顺序包含这两个头文件

是的:

否:


这是一件“坏事”。提到了更好的方法;但我会详细说明

//a.h
#如果没有_
#定义_
//... 代码。。。
#恩迪夫
// -----------------
//b、 h
#如果没有_
#定义_
#包括a.h
//... 代码。。。
#恩迪夫
// -----------------
//main.cpp Try 1
#包括“b.h”//
STL或STD库甚至Boost是否存在某些包含必须以特定顺序出现的情况

对于标准,答案是肯定的,。我想Boost也是如此,尽管我还没有查过

根据C标准:

标准标题可以按任何顺序包含;每一个都可以包含一次以上 一个给定的范围,除了 包含
的效果取决于
NDEBUG
的定义(见7.2)

< C++标准有类似的措辞。


我的偏好是标题应该包含它们自己的依赖项,但我曾经与一些认为这是“浪费”的人合作过。在我看来,不让标题包含它们的依赖项是一个毫无价值的早期优化。

需要按特定顺序指定包含项几乎总是表明存在设计问题。减少不小心这样做的可能性的一种方法是将类的头文件作为第一个包含在实现文件中

// A.cpp
#include "A.h"
#include "boost/shared_ptr.hpp"
#include <vector>

class A {
// ...
};
//A.cpp
#包括“A.h”
#包括“增压/共享_ptr.hpp”
#包括
甲级{
// ...
};
例如,如果A.h使用的向量没有正确的#include,则A.cpp将无法编译


我不记得在哪里捡到的;它可能是由LakOS(一个真正可以使用更新的好书)的“大规模C++设计”。

< P>我喜欢按字母顺序包括标题,这使得很容易看到我已经做了什么。
如果一个lib因为顺序错误而无法工作,那么它就被破坏了,应该被修复,以便与顺序无关。

据我所知。这是很糟糕的做法。不过,最近我在代码中遇到了一个Windows标题和一些奇怪的界面

对我来说,这是一个糟糕的设计,不幸的是,如果我没记错的话,它恰好在包含socket/socket2的win32 API中。结果是,包含顺序中的错误将触发一组错误,而这些错误恰好来自任何地方,并且在依赖项更改了定义但代码仍在编译的情况下可能很难调试


在任何其他情况下,你仍然会遇到麻烦。如果因为y.h已经包含头x.h而不包含头x.h,则代码依赖于y.h对x.h的依赖关系。如果以后y.h被重构,并且不再需要y.h,则删除包含将破坏代码基础。这是耦合的标志(即使不是在类级别):代码库的一部分中的更改需要传播并扩展到代码的其他部分。

您应该使用include-guard和forward声明,这样您在包含头的顺序上就不会有太多问题

有时仍然需要首先或最后包含标题,不知道为什么。

(例如:在源SDK中)

这可能是您正在使用MFC的一个迹象,而MFC又可能表示设计不好(笑话……或者是吗?)


(至少,上次我看MFC时,它对包含的位置非常挑剔)

将项目级兼容性头(比如compat.h)作为任何.c/.cpp源文件的第一个头是一种常见的技术,它定义了一组必需的宏,如u STDC\u LIMIT\u宏,_uu可重入宏和其他项目范围的宏,以影响标准标头的后续行为


很久以前,我第一次看到这个用法是由一个有能力的程序员为一个内部库编写的。后来我看到“Git”(臭名昭著的DVCS)项目也使用了这个技术。

< P>是的,在C++中包含一定的顺序是一个坏的库/头设计的标志。 尽管转发声明可能需要包含多个文件才能充分使用一个类。见下例:

//A.h

class B; // forward declaration

class A
{
    void doStuff(const B& b);
};
//main.cpp

#include <A.h>
#include <B.h>

int main()
{
    A a;
    B b;
    a.doStuff(b);
}
#包括
#包括
int main()
{
A A;
B B;
a、 多斯塔夫(b);
}

+1:臭味。还有一个标准的#ifdef三明治来确保所有.h都包含其所有适当的依赖项。特别是因为在头上放置保护条件非常容易,因此它们只包含一次,这使得“优化”完全无用。同意。编译器可以优化掉额外的包含,如果你跳过它们,如果你的一个包含头变为不包含你需要的东西,你就会陷入混乱。撇开远期声明不谈,当它们适用时,也就是说。嗯,我认为你把你的“a”和“b”搞砸了。在文件a.h的第5行中,您包括了b.h.b
// A.cpp
#include "A.h"
#include "boost/shared_ptr.hpp"
#include <vector>

class A {
// ...
};
class B; // forward declaration

class A
{
    void doStuff(const B& b);
};
#include <A.h>
#include <B.h>

int main()
{
    A a;
    B b;
    a.doStuff(b);
}