C++ 在必须传回值时避免循环包含

C++ 在必须传回值时避免循环包含,c++,C++,在我有一个类与另一个类(如API)通信并从该类获取回调的情况下,处理循环包含的最佳方法是什么 假设我有课 h .cpp 及 h .cpp 如果请求者发送了一个请求,并且api在某个时候获得了一个id,并希望将该id传递回请求者,那么在不包含彼此的.h文件(这将导致循环包含)的情况下,我如何做到这一点? 假设我不能简单地让函数MakeRequest返回id,因为我不想在api获得id之前保留该线程 我对C++和编程比较陌生,所以我可能会错过明显的解决方案。因为我需要调用彼此的成员函数,所以我的理解

在我有一个类与另一个类(如API)通信并从该类获取回调的情况下,处理循环包含的最佳方法是什么

假设我有课

h

.cpp

h

.cpp

如果请求者发送了一个请求,并且api在某个时候获得了一个id,并希望将该id传递回请求者,那么在不包含彼此的.h文件(这将导致循环包含)的情况下,我如何做到这一点? 假设我不能简单地让函数MakeRequest返回id,因为我不想在api获得id之前保留该线程

我对C++和编程比较陌生,所以我可能会错过明显的解决方案。因为我需要调用彼此的成员函数,所以我的理解是转发声明在这里不起作用

此外,Api和请求程序应该是独立的库,所以我不能将它们设置为一个类。

使用

#ifndef __filex__  
#define __filex__  
在每个的开头。h和

#endif
最后


通过这种方式,.h文件只被读取一次

您有两个不同的问题:类之间的循环依赖关系和同一头文件的多次包含

多重包含不仅仅是由简单的循环依赖项引起的,就像在您的案例中一样。确保头在源文件中包含一次且仅包含一次的常用方法是使用includeguard。通常,头文件如下所示:

#ifndef SOME_UNIQUE_NAME_
#define SOME_UNIQUE_NAME_

... header contents ...

#endif
这确保了无论头在源文件中包含多少次(直接或间接),只有在第一次实际包含其内容时,预处理器才会由于该宏跳过后续包含。宏名称必须是唯一的(出于明显的原因),它通常是某种前缀,后跟头名称,例如
LIBNAME\u MODULENAME\u REQUESTOR\u H

据我所知,大多数现代编译器都支持一种广泛使用的替代方法,即在头的开头使用
pragma
指令:

#pragma once

... header contents
另一个问题是类之间的循环依赖关系。在这里,您已经找到了一种解决方法:您的
Api
类持有一个指向
请求者的指针,而不是对象本身。这允许您在
Api.h
中使用转发声明,而不包括完整的类定义。
然而,
Requestor
类拥有一个
Api
对象,而不仅仅是一个指针,因此完整的
Api
类定义必须在声明
Api\uu
成员的位置可用。因此,您不能对
Api
类使用转发声明。在这种情况下,您必须实际包含完整的定义。

您是否尝试将
Api.h
包含在
Requestor.h
中?您需要非指针成员的定义。不会有循环包含。您可以在请求程序中有一个指向Api的指针,在构造函数中创建它,在析构函数中删除它,而不是实例。或者,如果您想大量输入,请使用自动打印。@cup
auto\u ptr
已被弃用,不应再使用。应使用
shared_ptr
unique_ptr
弱_ptr
中的一种。为避免循环包含,您需要使用一次include-guard或
pragma
。有关更多详细信息,请参阅您不应在大写字母前添加单个
。我建议甚至不要使用
\uuu
。标准库对其库使用此约定,如果使用相同的约定,则可能会弄乱代码。有关更多详细信息,请参见(虽然这是关于c的,但与c++相同),您最好选择在回答中提到的google样式指南中推荐的样式。
#ifndef __filex__  
#define __filex__  
#endif
#ifndef SOME_UNIQUE_NAME_
#define SOME_UNIQUE_NAME_

... header contents ...

#endif
#pragma once

... header contents