在必须传回值时避免循环包含
avoiding circular inclusion when having to pass back values
在我有一个类与另一个类(如API)通信并从该类获得回调的情况下,处理循环包含的最佳方法是什么?
假设我有一个类
. h
class Requestor;
class Api
{
public:
Api();
void Request();
int DoStuff();
private:
Requestor *p_rq_;
};
. cpp
#include "api.h"
#include "requestor.h"
Api::Api()
{
}
void Api::Request() {
this->DoStuff();
}
void Api::ReturnRequestId( int id ) {
this->p_rq->SetLastRequestId( id );
}
和
. h
class Api;
class Requestor
{
public:
Requestor();
void MakeRequest();
void SetLastRequestId( int );
private:
Api api_;
int last_request_id_;
};
. cpp
#include "requestor.h"
#include "api.h"
Requestor::Requestor()
{
}
void Requestor::MakeRequest() {
this->api_.Request();
}
void Requestor::SetLastRequestId( int id ) {
this->last_request_id_ = id;
}
如果请求者发送请求,并且在某些时候api获得id并希望将其传递回请求者,我怎么能在不包括彼此的。h文件的情况下做到这一点,这将导致循环包含?假设我不能简单地让函数MakeRequest返回id,因为我不想保持这个线程,直到api得到id?
我对c++和编程相当陌生,所以我可能会错过明显的解决方案。由于我需要调用彼此的成员函数,我的理解是前向声明在这里不起作用。
另外,Api和Requestor应该是独立的库,所以我不能让它们成为一个类。
你有两个不同的问题,类之间的循环依赖和多个包含相同的头文件。
多重包含不仅仅是由简单的循环依赖引起的,就像你的情况一样。确保头文件在源文件中只包含一次的常用方法是使用include守卫。通常头文件看起来像这样:
#ifndef SOME_UNIQUE_NAME_
#define SOME_UNIQUE_NAME_
... header contents ...
#endif
这确保了无论头文件在源文件中被包含多少次(直接或间接),只有第一次实际包含它的内容,由于该宏,后续的包含被预处理器跳过。宏名必须是唯一的(原因很明显),它通常是头名后面跟着某种前缀,例如LIBNAME_MODULENAME_REQUESTOR_H_
.
一个广泛使用的替代方法,被大多数现代编译器支持,即使据我所知不是标准的,是在头开始使用pragma
指令:
#pragma once
... header contents
你的另一个问题是类之间的循环依赖。这里你已经找到了一种绕过它的方法:你的Api
类持有一个指向Requestor
对象的指针,而不是对象本身。这允许您在Api.h
中使用前向声明,而不包括完整的类定义。然而,Requestor
类持有一个Api
对象,而不仅仅是一个指针,所以在声明api_
成员的地方必须有完整的Api
类定义。因此,在这种情况下,您不能为Api
类使用前向声明,您必须实际包含完整的定义。
使用
#ifndef __filex__
#define __filex__
在每个。h和
的开头#endif
在结尾。
这样,.h文件只被读取一次
- 在命名空间内使用函数的循环包含
- 解决C++中 3 个类的循环包含
- 循环包含依赖项/转发声明
- 由于循环包含导致Visual C++生成错误
- 变量已在 .obj 中定义,但没有循环包含
- 模板化函数导致循环包含
- 扩展类c++的循环包含问题
- 不能使用循环包含转发声明
- 循环包含导致链接错误的语句
- C++问题创建类对象和循环包含
- C++调用没有循环包含的成员函数
- C++循环包含
- 循环包含在C++中
- 在必须传回值时避免循环包含
- 循环包含在c++头文件中隐藏实现细节的技巧
- 错误:"{"标记之前的预期类名 - 似乎找不到任何循环包含
- 循环包含,如何在不更改类层次结构的情况下解决此问题
- 由循环包含的好友功能
- 互惠友元成员函数=循环包含声明
- 在c++中,由于类中的枚举,循环包含