我也看到过类似的问题,但不像我所处的困境。我正在处理别人的代码,他们的结构是这样的。
//db_manager.h
class db_manager
{
class error;
bool logError(error::def_enum::Value v, string msg);
bool read(int id);
}
//db_manager.cpp
#include db_manager.h
bool logError(error::def_enum::Value v, string msg)
{
return error::logError(v, msg);
}
bool read(int id)
{
//do db access stuff
return true;
}
//error.h
#include db_manager
class error
{
bool read(int id);
}
//error.cpp
#include error.h
bool read(int id)
{
return db_manager::read(id);
}
bool logError(error::def_enum::Value v, string msg)
{
//do error service stuff
}
这是一个非常明显的简化,但希望它能说明问题。
编译时,每当在db_manager.cpp中使用错误时,我都会得到很多不完整的类型错误,并且我无法将错误中的相关头文件包含在db_manager.cpp中,因为那样的话我必须将其添加到db_managers cmake依赖关系,这意味着我必须在package.xml中列出它,然后它才因循环依赖关系而烦恼。我该如何解决?我想,如果我可以在db_manager中使用错误的成员而不将错误作为依赖项,那会很好,但是我只是不知道该怎么做。我在这里看到了许多其他的前向声明问题,但是对于所有这些,声明的类用法都不是很深入。在这里,我使用的是类成员,而不是像其他问题一样声明类指针。
我绝对可以使用帮助,只是在没有完全废弃错误包并编写新包的情况下,我看不出有任何逻辑方法可以做到这一点。
编辑:而且,我简化了这个过程,但也许我不应该这样做。错误和db_manager位于两个单独的程序包中。
答案 0 :(得分:1)
首先:您的示例非常糟糕。请提供一个最低限度的示例。我了解您的问题是什么(循环依赖),但是您的示例未显示此问题。这是您必须在体系结构级别上解决的问题。您无法在CMake中解决此问题。
根据您显示的代码,您不需要在error.h中包含db_manager.h,因为在声明Error类时您没有使用db_manager中的任何内容。您只需要将它包含在error.cpp中,因为您正在使用db_manager中的一种静态方法。这样,您就没有任何循环依赖。
我在下面添加了一个最小的工作示例,该示例可以正确编译。
error.h
#ifndef _ERROR_H_
#define _ERROR_H_
#include <string>
class Error
{
public:
enum def_enum{ Val1, Val2};
bool read(int id);
static bool logError(def_enum v, std::string msg);
};
#endif /* _ERROR_H_ */
error.cpp
#include "error.h"
#include "db_manager.h"
bool Error::read(int id)
{
return db_manager::read(id);
}
bool Error::logError(Error::def_enum v, std::string msg)
{
//do error service stuff
return true;
}
db_manager.h
#ifndef _DB_MANAGER_H_
#define _DB_MANAGER_H_
#include <string>
#include "error.h"
class db_manager
{
public:
static bool logError(Error::def_enum v, std::string msg);
static bool read(int id);
};
#endif /* _DB_MANAGER_H_ */
db_manager.cpp
#include "db_manager.h"
bool db_manager::logError(Error::def_enum v, std::string msg)
{
return Error::logError(v, msg);
}
bool db_manager::read(int id)
{
//do db access stuff
return true;
}
main.cpp
#include "db_manager.h"
#include "error.h"
int main(){
db_manager::read(1);
db_manager::logError(Error::Val1, "Test");
Error e;
e.read(2);
return 0;
}
CMakeLists.txt
project(db_manager)
add_executable(executable main.cpp db_manager.cpp error.cpp)