Как избежать слишком большого количества аргументов в функции. C ++ - PullRequest
0 голосов
/ 24 апреля 2020

Я делаю небольшую игру на своем небольшом игровом движке, созданном на OpenGL c ++. Мне нужно сделать много классов, таких как Камера, BatchRenderer, AudioEngine, ParticleEngine, Уровень, Игрок, Зомб ie, Люди и т.д. c. Теперь игрок должен взаимодействовать с такими классами, как Camera, BatchRenderer, AudioEngine, ParticleEngine, данные уровня из класса Level, Zomb ie, Human, et c. И я передаю большинство из них по ссылке, которая инициализирована в моем классе основной игры.

// 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, зомби, люди, чтобы проверить обнаружение столкновений с игроком.

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

Здесь вы можете увидеть, что слишком много аргументов передается классу игрока, а также нужно больше в будущем. Но я читал много людей, говорящих, что плохо иметь более двух или трех аргументов в функции. И в моей игре есть много классов, которые принимают более 5 или 6 аргументов.

Правильно ли это для игры или это плохая практика? Пожалуйста, скажите мне, как я могу решить эту проблему.

Извините за плохой английский sh. Большое спасибо за чтение.

Ответы [ 4 ]

0 голосов
/ 24 апреля 2020

использование структуры содержит аналогичные аргументы, такие как:

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

Player :: Player (Shape & shape);

0 голосов
/ 24 апреля 2020

Слишком много аргументов в функции - это плохо, но это не масштабируемо и чисто. Это вызывает неудобство для пользователя и вам будет трудно поддерживать его. Вы не можете добавлять или удалять параметры в функции, это займет много времени. Еще одна вещь, вам не нужно делать слишком длинную структуру. Если структура становится слишком длинной, она разбивается на значимые структуры.

0 голосов
/ 24 апреля 2020

Если вы действительно обеспокоены этим, вы можете передавать аргументы в структуре. Он не менее эффективен в том, что касается компилятора.

Если у вас есть 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 каждый год:)

0 голосов
/ 24 апреля 2020

Слишком много аргументов плохо, только если вы вызываете свою функцию много раз в вашей программе, поскольку вы платите за стоимость помещения параметра вашей функции в стек плюс косвенность вызова функции.

Если вы не вызываете эти функции много времени, не беспокойтесь об упаковке переменных.

Если вам нужно упаковать переменную, вы можете просто поместить их в struct и передать один аргумент к функции (обычно это ссылка, чтобы избежать копирования)!

...