2016-09-22 2 views
-1

Я долгое время изучал/читал о C++, но я почти ничего не написал. Поэтому, несмотря на то, что я хорошо разбираюсь в современной практике C++, у меня все еще нет хороших дизайнов.Могу ли я предотвратить распространение этого шаблона в моем дизайне?

Вот моя проблема. Предположим, у меня есть класс Board, который представляет игровое поле (например, шахматы, go и т. Д.). Основное хранилище для этой платы - std::array.

Там еще один класс GameRunner который владеет Board и отвечает за запуск правил игры, вести счет и т.д.

Игра плата имеет размер, определенный пользователем. В моей голове GameRunner просто объявлялся как таковой: GameRunner::GameRunner(unsigned size), а затем size Параметр также передается в Совет, который объявлен: Board::Board(unsigned size).

Проблема в том, что std::array должен иметь размер, статически определенный. Поэтому у меня не может быть переменной-члена std::array, потому что во время компиляции я не знаю, какой будет размер. Я думал, что могу сделать std::unique_ptr как мой член, а затем указать эту точку на динамически созданный массив, но, конечно, вам нужно определить std::unique_ptr<std::array<???????>>, где вопросительные знаки обозначают, как я, очевидно, не знаю размер этого массива.

Итак, мое решение состояло в том, чтобы сделать Совет шаблону, чтобы пройти в размере ... так что GameRunner будет иметь Board<size>, но тогда, конечно, GameRunner также должен иметь шаблон, так что теперь это шаблоны до конца ...

Так что мне делать здесь? Шаблоны полностью вниз? Использовать контейнер с переменным размером, даже если размер не должен меняться? Я чувствую, что есть что-то невероятно тривиальное, что мне не хватает ...

+0

Вы можете сделать доску размером в векторе ... обменять неизмеримую разницу во времени выполнения для простого кода и ускорить время разработки –

ответ

2

Было предложение добавить контейнер для этой ситуации к стандарту C++ - тот, который определил бы его размер при его создании и никогда не изменится после этого. Это было отклонено, но довольно легко написать свои собственные, если хотите. В качестве альтернативы просто используйте std::vector и живите с тем фактом, что у вас есть функции, которые вам не нужны или не заботятся (но это вряд ли вызовет проблему).

+0

На всякий случай кому-то интересно, контейнер, о котором идет речь, [std :: experimental :: dynarray] (http://en.cppreference.com/w/cpp/container/dynarray) – Drop

2

Вы должны использовать std::vector<T> вместо std::array<T, N>.

+0

Я знаю, что std :: vector - это решение. Но для обучения я хочу знать, есть ли лучший способ создать массив на основе стека с фиксированным размером, размер которого определяется во время выполнения, а не comiletime. Если нет способа, и 'std :: vector' - единственный способ, то я буду жить с этим. – andy

+0

Разрешено иметь массивы на основе стека с определенным размером времени выполнения, но вы не можете иметь их в объектах, потому что тогда размер объекта станет переменным, что значительно усложнит ситуацию. Например, вы не сможете создать массив таких объектов. Существует и другое соображение: стек обычно намного меньше кучи, поэтому лучше выделять большие объекты в кучу. Таким образом, вы не можете иметь этот массив в стеке, и вы не можете получить его непосредственно внутри класса Board. И если он находится в куче, то std :: vector является самым естественным и простым решением. –

+2

@AlexeyGuseynov «Разрешено иметь массивы на основе стека с определенным размером времени« IINM, строго говоря, это разрешено на C99, но не на C++. Это правда, что 'g ++' поддерживает его, но это непереносимое расширение языка для компилятора (см. [Здесь] (http://stackoverflow.com/questions/20010716/gnu-compilers-vs-visual-studio-on- массивы-распределенные-W-длина-константы-ш-в-SC)). –

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