【问题标题】:Calling member method of cyclic dependent classes调用循环依赖类的成员方法
【发布时间】:2011-12-13 15:14:37
【问题描述】:

我正在尝试设置一个模拟程序。模拟运行了多个步骤,模拟类应该调用一堆不同类的 ::step(),其中一个是 _experiment 类。

我无法让它工作,因为实验类需要模拟类,而模拟类需要知道实验类是什么,所以它们是循环依赖的。我已经尝试通过使用前向声明来解决它,但是我无法访问前向声明类的方法。那么向前声明的意义何在?谁能帮我?谢谢!

main.cpp

int main()
{
    _experiment experiment;
}

experiment.cpp:

#include "experiment.h"

_experiment::experiment()
{
    _simulation simulation;
    simulation.experiment = this;
    simulation.start();
}

void _experiment::step()
{
    //Apply forces to simulation
}

实验.h:

#include "simulation.h"

class _experiment {
public:
    void step()
};

simulation.cpp:

#include "simulation.h"

void _simulation::run()
{
    //Run simulation for 1000 steps
    for(int i = 0; i < 1000; i++)
    {
        experiment->step() //Calculate forces. Doesnt work (cant use member functions of forward declared classes. How to work around this?

        //Calculate motion
    }
}

simulation.h:

class _experiment; //Forward declaration

class _simulation {
public:
     _experiment* experiment
     void run();
};

【问题讨论】:

    标签: c++ class forward-declaration cyclic-dependency


    【解决方案1】:

    experiment.h 不需要包含simulation.h,或者转发声明_simulation,因为_experiment 的定义根本不依赖于_simulation

    您已经在simulation.h 中有一个前向声明或_experiment,这很好,因为_simulation 的定义包含指向_experiment 的指针,因此不需要完整的定义。

    缺少的是源文件中两个类的定义。包含来自两个源文件的两个头文件,因为它们确实需要类定义,并且一切都应该很好。

    一般来说,如果你在源文件中包含所有你需要的头文件,并且当你需要的不仅仅是前向声明时,只包含来自另一个头文件的头文件,那么你将主要避免循环依赖问题。

    您还需要在标头中添加包含保护,以避免在确实需要包含来自其他标头的标头时出现多个定义。

    那么前向声明有什么意义呢?

    它允许您声明一个类存在,而无需声明该类所依赖的任何其他内容。您可以做一些有用的事情,例如定义类的指针或引用,或者使用类作为参数或返回类型声明函数,只使用前向声明。你不能做任何需要知道班级规模或成员的事情。

    【讨论】:

    • 所以你需要包含/转发声明标题在标题中使用的所有内容,以及 cpp 在 cpp 中使用的所有内容?我认为通过在“experiment.cpp”中包含“experiment.h”,然后在“experiment.h”中写入#include“simulation.h”,“simulation.h”也会包含在“experiment.cpp”中。我已经按照你说的做了,现在可以了,谢谢!
    • 最好让源包含它需要的所有内容,而不是依赖于您知道一个标题恰好依赖于另一个标题。这种依赖关系将来可能会发生变化,除非它们确实需要,否则标题不包含其他标题当然是最好的。
    【解决方案2】:

    你在simulation.cpp中没有_experiment的定义,在源文件中包含experiment.h文件就可以了。

    此外,_experiment 类在您的示例中似乎没有使用_simulation,因此无需在experiment.h 中包含simulation.h。还要将include guards 添加到您的头文件中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      • 2018-07-17
      • 2016-07-12
      • 1970-01-01
      • 2011-09-18
      相关资源
      最近更新 更多