【问题标题】:C++ Includes and Circular dependenciesC++ 包含和循环依赖
【发布时间】:2011-03-23 16:22:08
【问题描述】:

更新:让我澄清一下我的文件并重申我的问题:

main.h

#include "other.h"

class MyClass
{
    public:
    void MyMethod();
    void AnotherMethod();

    OtherClass test;
}

main.cpp

#include "main.h"

void MyClass::MyMethod()
{
    OtherClass otherTemp;     // <--- instantitate OtherClass object
    otherTemp.OtherMethod();  // <--- in this method here, is where I want to also call MyClass::AnotherMethod()
}

void MyClass::AnotherMethod()
{
    // Some code
}

other.h

class OtherClass
{
    public:
    void OtherMethod();
}

other.cpp

#include "other.h"
void OtherClass::OtherMethod()
{
    // !!!! This is where I want to access MyClass::AnotherMethod(). How do I do it?
    // I can't just instantiate another MyClass object can I? Because if you look above in 
    // main.cpp, this method (OtherClass::OtherMethod()) was called from within
    // MyClass::MyMethod() already.
}

所以基本上我想要的是:你实例化对象 A,然后实例化对象 B,它又调用来自对象 A 的方法。我确信这样的事情是可能的,但它可能只是我的设计很糟糕。任何方向将不胜感激。

【问题讨论】:

  • 为什么需要在.h访问它?
  • 对于同类型问题的另一个镜头,请参阅stackoverflow.com/questions/1655096/…
  • 我并不是要让任何人假设我在头文件中执行我的实现。我已经重申并澄清了我最初的问题。
  • 好的,你试过了吗?根据您实现它的方式,您最终可能会出现无限递归(OtherMethod 调用 AnotherMethod 和 ...)但这与循环依赖无关——即使您应该尽量避免循环。
  • 我已经更新了我的答案以解决对另一个方法的调用

标签: c++ include circular-dependency


【解决方案1】:

有些人每堂课一个 .h/.cpp:

我的.h

#ifndef MY_H
#define MY_H
#include "other.h"
class MyClass
{
    public:
    void MyMethod();

    OtherClass test;
}
#endif // MY_H

其他.h

#ifndef OTHER_H
#define OTHER_H
class OtherClass
{
    public:
    void Othermethod();
}
#endif // OTHER_H

我的.cpp

#include "my.h"
void MyClass::MyMethod() { }

其他.cpp

#include "other.h"
#include "my.h"
void OtherClass::OtherMethod)()
{
   // (ab)using MyClass...
}

如果您只使用 Visual Studio,则可以使用 #pragma once 而不是 #ifndef xx_h #define xx_h #endif // xx_h。 编辑:正如评论所说,GCC 也(至少)支持相关的Wikipedia page#pragma once

更新: 关于更新后的问题,与#include 无关,但更多的是关于传递对象...

MyClass 已经有一个嵌入的 OtherClass 实例,test。所以,在 MyMethod 中,它可能更像是:

void MyClass::MyMethod()
{
    test.OtherMethod();
}

如果 OtherMethod 需要访问 MyClass 实例,请将这个实例作为引用或指针传递给 OtherMethod:

参考

class OtherClass { public: void OtherMethod(MyClass &parent); }

void MyClass::MyMethod() { test.OtherMethod(*this); }

void OtherClass::OtherMethod(MyClass &parent)
{
   parent.AnotherMethod();
}

按指针

class OtherClass { public: void OtherMethod(MyClass *parent); }

void MyClass::MyMethod() { test.OtherMethod(this); }

void OtherClass::OtherMethod(MyClass *parent)
{
   if (parent == NULL) return;  // or any other kind of assert
   parent->AnotherMethod();
}

【讨论】:

  • GCC 套件也支持#pragma once。
  • 每个头文件一个类(其中头文件以类命名)是一个很好的方法。以这种方式总是很容易找到您要查找的内容。
【解决方案2】:

在 C++ 源文件中的任一类之外定义函数,而不是在头文件中:

void OtherClass :: Othermethod() {
   // call whatever you like here
}

【讨论】:

    【解决方案3】:

    创建一个 .cpp 文件:

    #include "main.h"
    
    void OtherClass::Othermethod()
    {
        MyClass m; //ok :)
        m.MyMethod(); //also ok.
    }
    

    无论如何,实现都不属于标头。

    【讨论】:

      【解决方案4】:

      只需将其#include 到 other.cpp 中

      【讨论】:

        猜你喜欢
        • 2012-02-19
        • 2016-06-09
        • 1970-01-01
        • 2012-04-24
        • 1970-01-01
        • 1970-01-01
        • 2012-06-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多