【发布时间】:2012-12-17 11:39:46
【问题描述】:
我有一个构造函数,它使用内部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 对象的实例。如果从链中省略一个Builder 方法,构造函数似乎也不允许默认NULL(至少从我所见)。现在,客户端必须要么给Weapon 一个指向NULL 的指针,要么给一个对象的实例。
有没有办法在不完全修改 Builder 构造函数的情况下解决这个问题?或者,是否应该使用另一种模式(例如Factory)对其进行重构,然后返回到带有位置参数列表的常规构造函数?
【问题讨论】:
-
请告诉我们
Player::Builder函数? -
我的第一个想法是智能指针。那将完全消除 cleanMemory()。
-
我想看看
Builder的构造函数。 -
@Mooing Duck 和@billz:
Builder的构造函数只是默认构造函数,但既然你提到了它,我现在看到我可能可以在那里初始化指针类型的值。谢谢。 -
我很好奇这个调用是怎么可能的,所以我想看看源代码。
Player* player = Player::Builder() .name("Dylan") .description("Super bad-ass hero of the game") .primaryAttributes(createPrimaryAttributes()) .abilityAttributes(createAbilityAttributes()) .weapon(createWeapon()) .armor(createArmor()) .build();
标签: c++ pointers memory-management null builder