Мой первый вопрос: является ли плохой практикой делать массив объектов Card общедоступным в классе Deck?
Да.В общем, члены данных всегда должны быть приватными.Полезно ООП создать интерфейс без ассоциированных данных, который определяет, какие операции могут быть выполнены над объектом, а затем предоставить конкретный класс, реализующий этот интерфейс.Данные - это детали реализации, которые не должны быть видны в интерфейсе или даже в полностью конкретном классе.В качестве примера того, почему это плохо, вы можете реализовать свой класс с помощью массива объектов Card прямо сейчас, но, возможно, позже вы решите использовать набор битов, где один бит указывает, присутствует ли карта в колоде или нет.Если вы сделаете объект массива Card общедоступным, изменение представления таким образом нарушит работу других пользователей вашего класса;однако, если вы оставите его закрытым, вы можете внести это изменение, не влияя на пользователей вашего класса.
Другой вопрос: как обычно перемещаются объекты, такие как объект Card, использованный в моей программе для игры в блэкджек?из объекта, подобного дилеру, ко второму объекту, например игроку?
Это зависит от того, нужен ли другому объекту доступ к исходному объекту карты, будет ли другой объект удерживаться на оригиналеобъект в течение длительного времени или только в течение короткого времени, или если другой объект может обрабатывать только копию карты.Это также зависит от того, является ли карта конкретным классом или полиморфным типом, поскольку полиморфные объекты могут быть переданы только по указателю или по ссылке (поскольку передача полиморфных объектов по значению приведет к нарезке кода).С конкретными объектами у вас есть возможность передать копию, если вам не нужно изменить или получить доступ к исходному объекту, и в этом случае требуется ссылка.Выбор правильного способа передачи объектов несколько сложен, но, надеюсь, это прояснит:
Передача по значению, если:
Это примитивный тип или небольшой, неполиморфный конкретный тип, который ненеобходимо изменить.
Передать по константной ссылке - то есть const T&
для некоторого типа T
- если:
- Вам не нужно изменять исходный объект.
- Вам не нужно читать исходный объект вне области действия функции.
- Вам не нужно читать объект вне области действия функции, или тип не является-полиморфный и дешевый для копирования, поэтому вы можете создать копию, если вам нужно повесить его.
Передача по ссылке - это T&
для некоторого типа T
- если:
- Вам необходимо изменить исходный объект.
- Вам не нужно читать / писать оригинальный объект вне области действия функции.
- Вы делаетене нужно читать объект за рамками функции или типОн не полиморфный и дешевый для копирования, поэтому вы можете создать копию, если вам нужно повесить ее.
Передача константным умным указателем на const - это const shared_ptr<const T>&
для некоторого типа T
- если:
- Вам необходимо прочитать исходный объекткак в области действия функции, так и за ее пределами.
- Вам необходимо прочитать объект как в области действия функции, так и за ее пределами, а тип является неполиморфным, так что невозможно безопасно создать копиюоб этом.
Передача с помощью постоянного интеллектуального указателя - то есть const shared_ptr<T>&
для некоторого типа T
- если:
- Вам необходимо прочитать и написатьоригинальный объект как в рамках функции, так и за ее пределами.
Я дал каждому из вышеперечисленных в преднамеренном порядке; Вы должны попробовать первый, который будет достаточен для работы, переходя к следующему, только если предыдущего недостаточно. Кроме того, я должен добавить, что boost :: call_traits :: param_type может помочь вам выбрать между передачей по значению и передачей по константной ссылке в случае конкретных неполиморфных типов (это можно определить на основе по размеру объекта, лучше ли передать по значению или передать по постоянной ссылке).