【问题标题】:C++ How to have a class relying on a namespace and that namespace relying on the class?C ++如何让一个依赖于命名空间的类和依赖于该类的命名空间?
【发布时间】:2016-07-25 16:06:28
【问题描述】:

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

这看起来像:

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'

我已经搜索过其他用户发布的这个问题,但是我没有成功找到一个帖子。

如果有人对此问题有疑问并认为需要给它差评,那么还请添加评论说明为什么这是一个不好的问题,以帮助我下次避免同样的错误。

提前感谢大家的帮助。

【问题讨论】:

  • 经典之作。请在 SO 中搜索递归包含或头文件组织。
  • Josh 这是一个打字错误,而不是实际代码的样子。感谢您指出这一点,我已经编辑了主要帖子以反映这一点。
  • 你知道大卫的解决方案吗?这就是这里的问题,但我只是不知道如何解决它
  • @MikeO 您可以对未定义类型的指针 使用前向声明,但不能对未定义类型本身使用前向声明。这里的正常方法是声明SomeNamespace::SomeStructure* instance1, instance2;。当然这意味着instance1instance2 必须动态分配。
  • 我也已经有了前向声明 drescherjm

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


【解决方案1】:

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

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

【讨论】:

  • 注意递归包含被删除了。
  • 我已经尝试过了,在 SomeFunction 定义中我调用 SomeClass 的成员函数时收到错误消息:'left of must point to class/struct/union/泛型'
  • 我通过在 .cpp 文件中添加 #include "Company.h" 来解决这个问题。谢谢你的回答。
【解决方案2】:

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

【讨论】:

  • 还要注意,pInstance1pInstance2 的创建也可能在 SomeClass.cpp 内部发生,在 SomeStructureSomeClass 都完全定义之后。
【解决方案3】:

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

#include "SomeClass.h"

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-26
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 2012-10-16
    相关资源
    最近更新 更多