多个C++文件和变量范围

Ske*_*ith 1 c++ scope

我有一个程序,它在winmain中启动,在其循环中调用run_game.

因为我将run_game视为主函数,所以我必须定义许多全局变量.

win main位于一个文件中,一切都在另一个.cpp文件中.它起初是一本书的教程,我现在已经加入了一段时间.因为我的代码变得如此之大,我想把它分成几个.cpp文件,但我有一些关于这样做的问题.

  1. 我看到很多人拥有一个巨大的源文件.我是自学成才,所以不确定这是否有好处或只是风格.

  2. 人们说应该避免使用全局变量,那么如何在其他文件中提供的函数中声明变量.

  3. 我的函数程序是否是一种糟糕的方法,因为我的计划是将run_game函数分解为几个较小的函数,每个函数都不是游戏的状态.

我知道人们可能会抱怨这是模糊的,所以如果你投票结束,请评论我如何能使问题更清楚.

编辑:我知道如何使用类,并在此程序的头文件中有4个类和3个结构,但类的实例与变量的作用相同,因此无法解决范围问题.

Dou*_* T. 6

我看到很多人拥有一个巨大的源文件.我是自学成才,所以不确定这是否有好处或只是风格.

通常更好的是具有较小的良好定义的文件而不是一个巨大的源文件.每个文件都有一个C++类定义或一组相互关联的函数.粗略的准则是不超过几百行的C++代码,但它的主观性和难以量化.您可能经常需要更少或更多.

人们说应该避免使用全局变量,那么如何在其他文件中提供的函数中声明变量.

您需要将这些变量作为参数传递给这些函数.例如,如果run_game调用foo,并且foo需要知道当前分数,则将分数作为参数传递,如下所示:

void run_game()
{
     int score = 0;

     ...
     foo(score);
}


void foo(int score)
{ 
    // do some stuff
}
Run Code Online (Sandbox Code Playgroud)

这被称为"按值传递",foo正在获得自己的分数副本.因此,如果foo更新得分,则调用者的副本将不会更新.您可以通过引用传递来让foo更新分数,如下所示:

void foo(int& score) // notice the ampersand
{
    // add 100 pts
    score += 100;
}
Run Code Online (Sandbox Code Playgroud)

现在你可能会问,我有50个变量,怎么可能把所有50个变成foo?这是软件工程的艰苦工作发挥作用的地方.你有几个选择.在任何选项中,您都要考虑变量的组合方式.您可能会发现您总是将相同的5个变量传递给函数foo.也许它是游戏中目前为止球员成就的一些表现.将这些组合在一起的最简单方法是使用结构:

struct PlayerAccomplishments
{
    int playersScore;
    int numGoblinsSlayed;
    int numTrollsSlaved;
};
Run Code Online (Sandbox Code Playgroud)

现在,您可以声明此类型的变量,设置特定字段并传递它们:

void run_game()
{
     PlayerAccomplishments accomplishments;

     ...
     foo(accomplishments);
}


void foo(PlayerAccomplishments& playerAccomps)
{ 
    // do some stuff
    playerAccomps.numTrollsSlayed++;
    playerAccomps.playerScore += 100;
}
Run Code Online (Sandbox Code Playgroud)

抽象的下一步是将一组变量和常用功能包装到一个类中.这使我们可以轻松地共享通用功能,并强制实施一种安全,好的方式来操作这些对象 - 由该对象的成员函数定义.例如,如果我们有一个球员类.

class Player
{
private:
    int score;
    int numTrollsSlayed;
public:
    // safely update the player's score after slaying a troll
    void SlayTroll(Troll& aTroll);
};

// in the cpp
Player::SlayTroll(Troll& aTroll)
{
    score += 100;
    numTrollsSlayed += 1;
}
Run Code Online (Sandbox Code Playgroud)

然后上面的代码变成:

void run_game()
{
     Player aPlayer;

     ...
     foo(aPlayer);
}


void foo(Player& aPlayer)
{ 
    Troll someTroll;
    aPlayer.SlayTroll(someTroll); // updates aPlayer's score
}
Run Code Online (Sandbox Code Playgroud)

我希望你能看到有很多方法可以考虑这些问题,并且不容易弄清楚如何分离出来.这个答案几乎没有触及表面.我推荐一本很好的软件工程课程或书.这个东西很难.具有数十年经验的真正聪明的人在组织和编写软件的最佳方式上挣扎.但考虑到这些东西很棒.努力寻找改进代码的方法是很好的,这样你就能够理解你今天,明天和六个月后想要做的事情.