C++ 在不引起循环依赖的情况下使用变量

C++ 在不引起循环依赖的情况下使用变量,c++,class,inheritance,include,C++,Class,Inheritance,Include,我有5套“.h”和“.cpp”文件: Main.cpp Game.h,Game.cpp Parent.h,Parent.cpp Child1.h,Child1.cpp Child2.h,Child2.cpp Main不包含类,也不包含头文件,它是应用程序的起点。除此之外,它使用收集的信息初始化“Game”类型的变量“myGame” Main.cpp #include "Game.h" ... Game myGame(*parameters sent to constructor*) 游戏是

我有5套“.h”和“.cpp”文件:

  • Main.cpp
  • Game.h,Game.cpp
  • Parent.h,Parent.cpp
  • Child1.h,Child1.cpp
  • Child2.h,Child2.cpp
Main不包含类,也不包含头文件,它是应用程序的起点。除此之外,它使用收集的信息初始化“Game”类型的变量“myGame”

Main.cpp

#include "Game.h"
...
Game myGame(*parameters sent to constructor*)
游戏是我的应用程序的主体。它的头包括Child1和Child2,并用这些类型初始化变量。它宣布类为“游戏”

Game.h

#pragma once

#include "Child1.h"
#include "Child2.h"

class Game
{
public:
    Game(HWND hWnd, ...);
    ~Game();

    Child1 child1Obj;
    Child2 child2obj[20];
    ...
private:
    ...
};
#pragma once

class Parent
{
public:
    Parent(void);
    ~Parent(void);
    ...
};
#pragma once
#include "Parent.h"

class Child1 :
    public Parent
{
public:
    Child1();
    ~Child1();
};
#pragma once
#include "Game.h"

Game myGame;
父类泛化两个子类,并提供类似的函数和变量。它的头不包括其他文件

Parent.h

#pragma once

#include "Child1.h"
#include "Child2.h"

class Game
{
public:
    Game(HWND hWnd, ...);
    ~Game();

    Child1 child1Obj;
    Child2 child2obj[20];
    ...
private:
    ...
};
#pragma once

class Parent
{
public:
    Parent(void);
    ~Parent(void);
    ...
};
#pragma once
#include "Parent.h"

class Child1 :
    public Parent
{
public:
    Child1();
    ~Child1();
};
#pragma once
#include "Game.h"

Game myGame;
Child1和Child2都类似,并且包含父标题

Child1.h

#pragma once

#include "Child1.h"
#include "Child2.h"

class Game
{
public:
    Game(HWND hWnd, ...);
    ~Game();

    Child1 child1Obj;
    Child2 child2obj[20];
    ...
private:
    ...
};
#pragma once

class Parent
{
public:
    Parent(void);
    ~Parent(void);
    ...
};
#pragma once
#include "Parent.h"

class Child1 :
    public Parent
{
public:
    Child1();
    ~Child1();
};
#pragma once
#include "Game.h"

Game myGame;
我希望能够使用
游戏中包含的数据,如
家长
Child1
Child2

我的第一个猜测是简单地将
#include“Game.h”
插入到
Parent.h
的顶部,但这样做会导致循环依赖

接下来,我认为只要在
游戏中使用变量和函数,就必须引用实际的游戏对象
myGame.
(在
Main.cpp
中创建)。但我不知道该怎么做。也许我可以在
Main.h
文件中预先声明
myGame
,如下所示:

Main.h

#pragma once

#include "Child1.h"
#include "Child2.h"

class Game
{
public:
    Game(HWND hWnd, ...);
    ~Game();

    Child1 child1Obj;
    Child2 child2obj[20];
    ...
private:
    ...
};
#pragma once

class Parent
{
public:
    Parent(void);
    ~Parent(void);
    ...
};
#pragma once
#include "Parent.h"

class Child1 :
    public Parent
{
public:
    Child1();
    ~Child1();
};
#pragma once
#include "Game.h"

Game myGame;
但为了做到这一点,我仍然必须使用
#包括“Game.h”
,并在我想要使用的
myGame
文件的顶部包括“Main.h”—这导致了与上述相同的循环依赖性问题

我有没有办法:

  • 在“Main.h”中声明类型为Game的未初始化的myGame
  • 使用“Main.cpp”中收集的信息初始化myGame
  • 在Parent、Child1和Child2中使用
    myGame
    ,通过包含在中声明的
    myGame
    文件,不会导致循环依赖

  • 我是否能够在“Main.h”中使用
    #include“Game.h”
    来创建游戏变量,但阻止对包含“Main.h”的文件进行include继承?

    向前声明允许引用尚未定义的对象,但在没有定义的情况下无法实例化它们。上面写着“我以后再告诉你”

    非法:

    class myGame;  // forward declaration, I'll tell you about this later
    class myPlayer
    {
    public:
      myPlayer();
    protected:
      myGame theGame;
    }
    
    法律:

    class myGame;  // forward declaration, I'll tell you about this later
    class myPlayer
    {
    public:
      myPlayer();
    protected:
      myGame* theGame;
    }
    
    您在头文件中向编译器承诺的“稍后”是源文件

    myPlayer.cpp:

    #inlcude "myPlayer.h"
    
    // Tell the compiler what a myGame is, 
    // other than something that can be pointed at
    #inlcude "myGame.h" 
    
    myPlayer::myPlayer() :
      theGame(new myGame())
    {
    }
    
    当然,一个真正的程序将实质上更加复杂,带有构造函数的参数等等。这个演示是关于类的结构、描述它们的文件以及它们的联锁关系

    前向声明的缺点是编译器无法获取有关被前向声明对象的信息,因此它无法生成前向声明,因此,它不能将一个前向声明放在另一个对象中。话虽如此,你可以指向一个,因为你说过有这样一个东西,你已经向前声明了,因此用这些东西做事情是合法的,比如取它们的内存地址,然后指向它们,或者引用一个


    当编译器深入到源文件.cpp时,您已经提交了正向声明对象的定义,现在它知道它们是什么以及可以用它们做什么。在这一点上,您可以使用指针或引用进行操作,例如创建一个
    新的
    one,或在其上调用函数。

    家长、孩子1和孩子2需要如何使用游戏?也许你可以对Game.MacklinB使用forward decls,当然这种问题在[C]和[C++]中都会出现。然而,问题代码显然不是[C]。也许你应该考虑编辑你的问题,去掉[C]标签?< <代码> >包含“游戏h”/<代码> <代码> Prime.CPP < /代码>。父类定义不能依赖于游戏,尽管它可以通过前向声明接受指针或引用。当然,
    Parent.cpp
    中的函数体可以使用full
    Game
    s。这解决了我在
    中出现的200多个错误,包括
    Parent.h
    中的“Game.h”
    ,但当我尝试在
    Parent
    类下使用任何类型时会导致错误。Child1和Child2也在我的类声明“Parent”:基类未定义时出错。您的编辑对我不起作用,因为在myPlayer.cpp中创建myGame实例时,我需要传递myPlayer中不可用的3个参数-但在Main中。@MaklinB,您在问题中没有提到这方面的任何内容。也许你想问一个新问题?