【问题标题】:C++ Accessing a class from a function it is not defined inC ++从未定义的函数访问类
【发布时间】:2017-03-23 15:04:01
【问题描述】:

我是 C++ 新手,在访问类中的变量时遇到了一些麻烦。从到目前为止我在这里读到的内容来看,创建全局变量是一种非常糟糕的做法,不要这样做,但我不知道如何移动对类的访问。

到目前为止,我的搜索已指示我在类中设置和获取函数,但我认为我只能在定义对象的块中使用它们。

基本上我想知道的是,如果我在 main() 中定义了一个类对象,然后在 main() 中调用一个函数,比如 gameLoop(),我如何在新函数中访问该对象而不使类对象成为全局对象。

例如:

#include "stdafx.h"
#include <iostream>
using namespace std;
#include <string>

class Word
{
    private:
        string m_word;
        int m_length;
    public:
        void set(string word, int length)
        {
            m_word = word;
            m_length = length;
        }
};

void gameLoop()
{
    word1.set(); //flags error as it cant acces the word1 object
    //I want to be able to access word1 from here
    //Not a copy because that wouldnt change the actual word1
    //I dont want to define it in here because then it would be created again
    //for each loop of gameLoop
}

int main()
{
    Word word1;
    int play = 1;
    while (play ==1){
        gameLoop();
    }
    return 0;
}

这是一个大大简化的版本,但出于游戏的目的,我希望将类存储在外部,但为了让 gameLoop 内的许多游戏功能能够访问和更改类对象。

【问题讨论】:

  • word1 作为参数传递给gameLoop
  • 将其作为参数传递gameLoop(Word word)
  • 作为参考可能更好 (gameLoop(Word&amp; word))
  • 顺便说一句,您的措辞听起来有点混乱。你想访问一个对象而不是一个类和函数中没有定义的类(现在可以做到,但通常你不这样做)
  • 或者你可以在main之外声明Word word1;(在全局范围内)——但这通常是一种不好的做法

标签: c++ function class


【解决方案1】:

理想情况下,函数的依赖关系应该在参数列表中声明。如果您的 gameLoop 函数需要 Word 对象,请将其作为参数传入。这样,就很清楚该函数需要哪些对象才能工作。这看起来像:

void gameLoop(Word& word)
{
    word.set();
    // ^ Obviously you need to supply args here. 
}

int main()
{
    Word word1;
    int play = 1;
    while (play ==1){
        gameLoop(word1);
    }
    return 0;
}

由于您在函数中改变 Word 对象,因此您需要通过引用传递它,否则您只是在修改副本。

您唯一的另一个明智的选择是使单词 object 全局化,但应不惜一切代价避免这样做。它使测试变得更加困难,因为您需要考虑可能发生的每一个变化,这使得隔离问题变得困难。

【讨论】:

  • 那么在这种情况下,word(在 gameLoop 中)与 word1(来自 main)是同一个对象吗?不是独立副本?
  • @UoMDan 如果你通过引用 (&amp;),是的。如果没有&amp;,则会制作一份副本。
  • 啊,我想这就是我一直在寻找的!我想我一直在制作副本,然后在每个循环中消失,但这听起来像是我所追求的。谢谢!
  • @UoMDan 是的,如果您不通过引用传递,则制作副本,您修改副本,然后在函数退出时将其销毁。另一种选择是返回修改后的单词副本。 如果它是gameLoop 中唯一被修改的东西,那也是一个可行的选择。由于我最近一直在编写函数式编程,我会说显式返回它比修改参数更好,但这可能是“反 C++ 风格”。自从我写 c++ 以来已经有几年了,所以惯用的 c++ 在我的脑海中并不新鲜。
【解决方案2】:

如果您以这种方式构建程序,则必须将其作为参数传递给gameloop

但是,这是一个非常糟糕的设计,因为您在 main 中创建并希望在 gameloop 中访问的任何内容都必须作为参数传入。我会考虑另一种方法。

您可以将整个循环和变量声明移动到gameLoop,如下所示:

void gameLoop()
{
    Word word1;
    int play = 1;
    while (play ==1){
        word1.set(/*args*/);
    }
}

int main()
{
    gameLoop();
    return 0;
}

这样您就不必将一百万个东西传递到游戏循环中。通常在游戏中也需要进行一些初始化和完成,这都可以在调用gameLoop之前/之后在main中完成。

因此,要回答您最初的问题,您必须将 word1 作为参数传递给 gameLoop()。所以重新定义你的函数以接受Word 参数,然后传入word1。但同样,我会在为时已晚之前重新考虑您当前的设计

【讨论】:

  • 我想我必须通过它,因为 gameLoop 也会有自己的功能,可能想要改变 word1 的内容
  • 我不知道我是否会强调需要这么大的设计更改。除非这是一个被标记的巨大项目,否则奇妙的搞砸是一种很好的学习方式。除非您编写了一些非常糟糕的代码,否则很难欣赏正确的设计。
  • @UoMDan 我不明白这与这有什么关系,因为你仍然可以 100% 做到这一点。
  • @Carcigenicate 我猜你是对的。我只是在想象一个需要传入的 100 个参数的列表。
猜你喜欢
  • 2019-01-18
  • 2017-12-11
  • 2011-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-26
相关资源
最近更新 更多