C ++如何让一个依赖于命名空间的类和依赖于该类的命名空间?

时间:2016-07-25 16:06:29

标签: c++ class struct namespaces forward-declaration

所以我有一个类,其中一些成员变量是在名称空间中定义的结构的实例,并且同一名称空间中的函数有一个参数,该参数是指向上述类的实例的指针。

这看起来像:

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;

我通过添加前向声明'类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
    {
        ...
    }
    ...

我试图修复错误2,为命名空间和结构做同样的事情:

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'

我已经搜索了其他用户发布的此问题,但找不到帖子我找不到。

如果有人对此问题有疑问并认为他们需要对其进行评分,那么请同时添加评论,说明为什么这是一个糟糕的问题,以帮助我避免下次犯同样的错误。

提前感谢大家的帮助。

3 个答案:

答案 0 :(得分:4)

根据您向我们展示的内容,您只需要SomeNamespace.h中的SomeClass的前向声明,而不是完整的包含:

#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的任何内容,除了它是一个类。

答案 1 :(得分:1)

如果您确实需要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

答案 2 :(得分:0)

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

#include "SomeClass.h"

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