2013-07-27 3 views
0

Я работаю над игровым проектом, и у моего товарища по команде есть определенный способ решения наших эталонных вопросов, и он отлично работает, если только игра не будет большой, мы получим массивные конструкторы.Инициализация ссылок в конструкторе

class Player 
{ 
    private: 
     Weapon *w1, *w2, *w3; 
     Armor *a1, *a2; 

    public: 
     Player(Weapon *w1, Weapon *w2, ...) : w1(w1), w2(w2), ...; 
} 

Тогда мой конструктор is Player(w1, w2, w3, ...); который вызывает беспокойство, что, если класс игрок имел 100 ссылок?

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

ВАЖНО Вышеприведенное является просто примером, плохо написанным. У меня нет оружия и доспехов. У меня много уроков. У меня есть ссылка на консоль разработчика, у меня есть ссылки брони, элементы, у меня есть ссылки на класс отладки, класс журнала, и список продолжается. Мне не нужен вектор. Извините за плохой пример.

+0

Если вам нужно передать десятки (или более) аргументов, то, скорее всего, вы делаете что-то неправильно. Пусть конструктор (ы) инициализирует переменные-члены для некоторого стандартного значения по умолчанию и просто изменит несколько, которые действительно нужно изменить. –

+2

Что касается этого случая, считаете ли вы ['std :: vector'] (http://en.cppreference.com/w/cpp/container/vector) вместо дискретных переменных? Если вы используете наследование, то этого может быть достаточно, чтобы иметь единственный вектор для * все * оборудования, независимо от вида. –

+1

И последний комментарий, и просто для nitpick, но на C++ вы не инициализируете ссылки, вы инициализируете * указатели *. Ссылки на C++ - это нечто другое. –

ответ

1

Почему бы не использовать vectors?

std::vector<Weapon *> W; 
std::vector<Armor *> A; 
+0

Потому что оружие и доспехи были просто примером. У меня есть оружие, доспехи, инструменты, консоль разработчика и так много классов. Большинство из них имеют уникальные элементы, поэтому вектор никоим образом не является решением для меня:/ –

+1

@ ZamriMalakun, тогда я бы сказал, что этого примера недостаточно, чтобы указать на конкретную структуру данных/stl container – P0W

+2

@ ZamriMalakun: вы можете рассмотрим использование полиморфизма. Если все различное оборудование происходит из общего класса «Оборудование», вы можете хранить их в одном контейнере. Если вам нужно быстро выбрать «тип» оборудования, вы можете создать «enum», чтобы различать разные типы и создать «std :: map >», чтобы удерживать все и все еще есть способ получить все оружие или все доспехи, не перебирая весь список оборудования. –

0

Вместо того, чтобы иметь фиксированное количество указателей на небольшое число типов, попробуйте использовать векторы:

class Player 
{ 
    private: 
     std::vector<Weapon*> weapons; 
     std::vector<Armor*> armors; 

    public: 
     Player(const std::vector<Weapon*>&, const std::vector<Armor*>&); 
} 
1

Вы действительно можете поместить все это в одном векторе, если использовать наследование.

Для фантазии тематических игр (которые я предполагаю, что вы пишете) это может быть что-то вроде этого:

// The base object, contains common attributes 
class Object { ... }; 

// The item class 
class Item : public Object { ... }; 

class Weapon : public Item { ... }; 

class Sword : public Weapon { ... }; 

class Clothing : public Item { ... } 

class Armour : public Clothing { ... }; 

Тогда это достаточно с один вектора всех оборудования:

std::vector<std::shared_ptr<Item>> inventory; 

Для изношенных вещей, вы могли бы иметь отдельные переменный, как

std::shared_ptr<Weapon> wielded; 
std::shared_ptr<Clothing> head; // Helmets, hats, etc. 

Или использовать карту для снаряженных вещей:

std::unordered_map<std::string, std::shared_ptr<Item>> equipped; 

Затем вы можете использовать, например,

equipped["wielded"] 

, чтобы получить предмет.


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

class Character : public Object { ... } 

class Player : public Character { ... } 

class Monster : public Character { ... } 

class Dragon : public Monster { ... } 

class RedDragon : public Dragon { ... } 

class TheUltimateBossDragon : public RedDragon { ... } 

В качестве примечания, я использовал иерархий, как выше в моих играх ранее. Однако в моей следующей игре (когда и , если я так далеко) Я, вероятно, буду использовать другой шаблон, где классы указывают на поведение. Например, sword - equipable, это damage_inflicter, это takeable и т. Д. Это означает более сложные иерархии наследования с гораздо большим количеством наследования и, вероятно, будет использовать RTTI больше. Но с яркой стороны, мы надеемся, будет более гибкой.

+1

Важное примечание для новичка: достаточно ** только **, если 'Object' или' Item' имеет открытый виртуальный деструктор. –

Смежные вопросы