У меня есть конструктор, который использует внутренний объект Builder
для создания экземпляра сложного объекта. Пять элементов в структуре данных относятся к типам указателей. Однако, используя этот шаблон, я сталкиваюсь с проблемами, когда объект уничтожается. Вот как выглядит мой конструктор со списком инициализации членов:
Player::Player(const Builder& builder)
:m_name(builder._name)
,m_description(builder._description)
,m_primaryAttributes(builder._primaryAttributes)
,m_abilityAttributes(builder._abilityAttributes)
,m_armor(builder._armor)
,m_weapon(builder._weapon)
,m_inventory(new ComponentMap())
{}
Клиентский код работает хорошо, как и ожидалось:
Player* player = Player::Builder()
.name("Dylan")
.description("Super bad-ass hero of the game")
.primaryAttributes(createPrimaryAttributes())
.abilityAttributes(createAbilityAttributes())
.weapon(createWeapon())
.armor(createArmor())
.build();
Однако, если я пропущу один из аргументов в цепочке сообщений, а затем уничтожу свой объект Player
, произойдет что-то плохое:
Player* player = Player::Builder()
.name("Dylan")
.description("Super bad-ass hero of the game")
.primaryAttributes(createPrimaryAttributes())
.abilityAttributes(createAbilityAttributes())
.armor(createArmor())
.build();
// ...
delete player;
// ...
// cleanMemory() gets called in Player::~Player()
void Player::cleanMemory()
{
if(m_primaryAttributes != NULL )
delete m_primaryAttributes;
if(m_abilityAttributes != NULL )
delete m_abilityAttributes;
if(m_inventory != NULL )
delete m_inventory;
if(m_weapon != NULL) // oops, bad stuff happens here
delete m_weapon;
if(m_armor != NULL)
delete m_armor;
}
Очевидно, это происходит потому, что указатель на оружие не был инициализирован ни NULL
, ни экземпляром объекта Weapon
. Конструктор также не допускает значение по умолчанию NULL
(по крайней мере, из того, что я вижу) в случае, если один метод Builder
опущен в цепочке. На данный момент клиент должен либо передать Weapon
указатель на NULL
, либо экземпляр объекта.
Есть ли способ обойти это, не пересматривая полностью этот конструктор Builder
? Или следует провести рефакторинг с использованием другого шаблона, такого как Factory
, и просто вернуться к обычному конструктору со списком позиционных параметров?
Player::Builder
? - person billz   schedule 03.01.2013Builder
. - person Mooing Duck   schedule 03.01.2013Builder
- это просто конструктор по умолчанию, но теперь, когда вы упомянули об этом, теперь я вижу, что я, вероятно, могу инициализировать там значения типа указателя. Спасибо. - person dtg   schedule 03.01.2013Player* player = Player::Builder() .name("Dylan") .description("Super bad-ass hero of the game") .primaryAttributes(createPrimaryAttributes()) .abilityAttributes(createAbilityAttributes()) .weapon(createWeapon()) .armor(createArmor()) .build();
- person billz   schedule 03.01.2013Builder
в этом посте: stackoverflow.com/questions/7520250/ - person dtg   schedule 03.01.2013NULL
перед выполнениемdelete
. - person Asha   schedule 03.01.2013