C++如何使一个类依赖于名称空间,而该名称空间依赖于该类

C++ How to have a class relying on a namespace and that namespace relying on the class?

本文关键字:空间 依赖于 何使一 C++      更新时间:2023-10-16

所以我有一个类,它有一些成员变量,这些变量是命名空间中定义的结构的实例,而同一命名空间中的函数有一个参数,它是指向上述类实例的指针。

这看起来像:

SomeClass.h

#ifndef SOME_CLASS_H
#define SOME_CLASS_H
include "SomeNamespace.h"
class SomeClass
{
private:
    SomeNamespace::SomeStructure instance1, instance2;
    ...

SomeNamespace.h

#ifndef SOME_NAMESPACE_H
#define SOME_NAMESPACE_H
#include "SomeClass.h"
namespace SomeNamespace
{
    namespace AnotherNamespace
    {
        void SomeFunction( SomeClass *pSomeClass );
    }
    struct SomeStructure
    {
        ...
    }
    ...

我收到的错误:

Error C2065 'SomeClass': undeclared identifier  
Error C2653 'SomeNamespace' : is not a class or namespace name

第一个错误与有关

void SomeFunction( SomeClass *pSomeClass );

第二个错误涉及:

SomeNamespace::SomeStructure instance1, instance2;

我通过添加前向声明"class SomeClass;"修复了第一个错误到文件顶部:

SomeNamespace.h

#ifndef SOME_NAMESPACE_H
#define SOME_NAMESPACE_H
#include "SomeClass.h"
class SomeClass;
namespace SomeNamespace
{
    namespace AnotherNamespace
    {
        void SomeFunction( SomeClass *pSomeClass );
    }
    struct SomeStructure
    {
        ...
    }
    ...

我试图修复错误二,对名称空间和结构做同样的事情:

SomeClass.h

#ifndef SOME_CLASS_H
#define SOME_CLASS_H
include "SomeNamespace.h"
namespace SomeNamespace
{
    struct SomeStructure;
}
class SomeClass
{
private:
    SomeNamespace::SomeStructure instance1, instance2;
    ...

对命名空间和其中的结构进行正向声明会导致以下错误:

'SomeClass::instance1' uses undefined struct 'SomeNamespace::SomeStructure'
'SomeClass::instance2' uses undefined struct 'SomeNamespace::SomeStructure'

我已经搜索了另一个用户发布的这个问题,但我一直没有找到一个帖子。

如果有人对这个问题有意见,觉得他们需要对它进行糟糕的评价,那么也请添加一条评论,说明为什么这是一个糟糕的问题,以帮助我下次避免同样的错误。

提前感谢大家的帮助。

根据您向我们展示的内容,您只需要在SomeNamespace.h中转发SomeClass声明,而不需要完整的include:

#ifndef SOME_NAMESPACE_H
#define SOME_NAMESPACE_H
// #include "SomeClass.h"  // << don't do this.
class SomeClass;
namespace SomeNamespace
{
    namespace AnotherNamespace
    {
        void SomeFunction( SomeClass *pSomeClass );
    }

上面的内容是有效的,因为指向SomeClass的指针不需要知道SomeClass除了是一个类之外的任何信息。

如果确实需要SomeStructureSomeClass之间的循环引用,则可以使用指针,因为不必事先完全定义底层类型。

SomeNamespace.h:

#ifndef SOME_NAMESPACE_H
#define SOME_NAMESPACE_H
#include "SomeClass.h"
namespace SomeNamespace {
    namespace AnotherNamespace {
        void SomeFunction(SomeClass *pSomeClass);
    }
    struct SomeStructure {
    };
}
#endif

SomeClass.h:

#ifndef SOME_CLASS_H
#define SOME_CLASS_H
namespace SomeNamespace {
    struct SomeStructure;
}
class SomeClass {
private:
    SomeNamespace::SomeStructure *pInstance1, *pInstance2;
public:
    SomeClass(SomeNamespace::SomeStructure *pInstance1, SomeNamespace::SomeStructure *pInstance2) 
        : pInstance1(pIntance1), pInstance2(pInstance2) {}
};
#endif

main.cpp:

#include "SomeNamespace.h"
#include "SomeClass.h"
int main(int argc, char* argv[]) {
    SomeNamespace::SomeStructure *pInstance1 = new SomeNamespace::SomeStructure();
    SomeNamespace::SomeStructure *pInstance2 = new SomeNamespace::SomeStructure();
    SomeClass someClass(pInstance1, pInstance2);
    return 0;
}

在本例中,main.cpp可以创建SomeStructure对象,因为它可以看到完全定义的类,并且出于同样的原因,它也可以实例化SomeClass

考虑包含以下内容的代码:

#include "SomeClass.h"

处理SomeClass.h时,将创建#define保护。然后打开并处理SomeNamespace.h。它的卫士被创造出来了。然后重新处理SomeClass.h——只有保护存在并阻止任何定义。这就是编译器生成未定义错误的原因。