【问题标题】:How to avoid too many arguments in a function. C++如何避免函数中的参数过多。 C++
【发布时间】:2020-08-07 15:02:17
【问题描述】:

我正在使用 OpenGL c++ 制作的小游戏引擎制作一个小游戏。 我必须制作许多类,如 Camera、BatchRenderer、AudioEngine、ParticleEngine、Level、Player、Zombie、Humans 等。现在 Player 必须与 Camera、BatchRenderer、AudioEngine、ParticleEngine、Level 类中的关卡数据、Zombie、Human 等类进行交互等。我通过在我的 Main Game 类中初始化的引用传递其中的大部分。

//在Main Game类和Player中创建的AudioEngine和ParticleEngine需要播放声音和模拟粒子。渲染播放器需要 TextureID、位置、半径(大小)、旋转、深度和颜色。

Player::Player(AudioEngine& a_audioEngine, ParticleEngine& a_particleEngine
               GLuint a_textureID, glm::vec2 a_position, float a_radius,
               float a_rotation, float a_depth, Color a_color)
{...}

// 用于检查玩家是否在视野中的相机。 levelData、僵尸、人类检查与 Player 的碰撞检测。

void Player::update(Camera& camera, std::vector<std::string>& levelData,
                    std::vector<Zombie>& zombies, std::vector<Human>& humans,
                    float deltaTime)

在这里您可以看到传递给玩家类的参数过多,并且将来还需要更多。 但是我读到很多人说在一个函数中有两个或三个以上的参数是不好的。在我的游戏中,有许多类需要超过 5 或 6 个参数。

这适合游戏还是不好的做法? 请告诉我如何解决这个问题。

抱歉英语不好。 非常感谢您的阅读。

【问题讨论】:

  • 也许您可以拥有一个包含当前游戏实例的所有相关对象的Game 类?可能可以重新设计事物以减少所需参数的数量。没有更多细节很难具体说明。
  • 你可以阅读中介者模式。这可能会有所帮助。
  • 你之前问过同样的问题。如果问题关闭,您可以对其进行编辑,然后将对其进行审核,如果问题得到解决,最终将重新打开 (stackoverflow.com/q/61390127/4117728)
  • 抱歉,有些人说这个问题不完整,而且缺乏信息。而且我认为更新问题是行不通的。
  • 你让你的球员承担了太多的责任。将音频、渲染、碰撞、游戏规则等“系统事物”留在播放器之外,让这些系统了解播放器(和其他事物)并对其所做的事情做出反应。

标签: c++ parameters arguments game-engine


【解决方案1】:

使用结构体包含类似的参数,例如:

struct Shape {
  float a_radius;
  float a_rotation;
  float a_depth;
  Color a_color;
  // ...
};

Player::Player(形状&形状);

【讨论】:

    【解决方案2】:

    如果你真的很关心它,你可以在结构体中传递参数。就编译器而言,它的效率并不低。

    如果你有 c++17,你可以使用结构化绑定解包结构以提高可读性。

    如果你有 c++20,你可以创建带有命名初始化的结构。

    例如:

    #include <string>
    
    struct vec {
        double x, y, z;
    };
    
    struct func_args {
        int a;
        std::string b;
        double c;
        vec x , y , z;
    };
    
    void foo(std::string const&, vec const&);
    
    void func(func_args const& args) {
        // c++17 feature - structured binding (in this case by reference)
        auto& [a, b, c, x, y, z] = args;
        foo(b, x);
    }
    
    // or by value...
    void func(func_args&& args) {
        auto [a, b, c, x, y, z] = std::move(args);
        foo(b, x);
    }
    
    void test()
    {
        // c++20 feature (and gcc extension prior). Named initialisation.
        func({ .a = 0, .b = "alien", .c = 0.0, 
            .x = { -1, 1, 0}, 
            .y = { -1, 1, 0}, 
            .z = { -1, 1, 0}});
    
        auto const args2 = func_args { 
            .a = 0, .b = "alien", .c = 0.0, 
            .x = { -1, 1, 0}, 
            .y = { -1, 1, 0}, 
            .z = { -1, 1, 0}};
        func(args2);
    }
    

    C++ 每年看起来更像 javascript :)

    【讨论】:

      【解决方案3】:

      函数中有太多参数是不好的,但它不可扩展和干净。它会导致用户使用功能不便,并且对您来说也很难维护。您不能在函数中添加或删除参数,这样做会花费大量时间。还有一件事你也不需要制作太长的结构。如果结构变得太长,则拆分为有意义的结构。

      【讨论】:

        【解决方案4】:

        只有当您在程序中多次调用函数时,参数过多才是不好的,因为您付出了将函数的参数放入堆栈的成本以及函数调用的间接性。

        如果您不经常调用这些函数,则不必费心打包变量。

        如果您需要打包变量,您可以将它们放入 struct 并将单个参数传递给函数(通常是避免复制的引用)!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-01-06
          • 1970-01-01
          • 2019-07-04
          • 2011-09-08
          • 2015-03-28
          • 2010-12-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多