我有一个Player
尝试实现该Decorator
模式的类。Player
包含其基类的成员,Character
称为m_player
. 从客户端调用析构函数时Player
,我遇到了一些导致内存访问冲突的问题。开始于main
:
Character* createBaseClass();
// more forward declarations
int main (int argc, char* const argv[])
{
Player* mainCharacter = new Player(createBaseCharacter());
delete mainCharacter; // Crashes when calling delete
return 0;
}
Character* createBaseCharacter()
{
return Character::Builder()
.name("Dylan")
.description("Super bad-ass hero of the game")
.build();
}
delete
在我调用操作员 on后不久发生错误,该操作员mainCharacter
具有以下调用顺序:
Player::~Player()
{
delete m_armor;
delete m_weapon;
delete m_player; // calls Character's destructor
}
然后是析构函数Character
:
Character::~Character()
{
// works fine
//
delete m_abilityAttributes;
m_abilityAttributes = NULL;
delete m_primaryAttributes;
m_primaryAttributes = NULL;
}
然而,奇怪的是,这个析构函数似乎被调用了两次——一旦完成上述操作,调试器就会带我进入一个反汇编,逐步通过“标量删除析构函数”,它似乎Character
再次调用析构函数,通过的接口Player
,称为CharacterDecorator
:
崩溃点的调用堆栈:
调用CharacterDecorator
' 的析构函数会导致随后调用Character
' 的析构函数:
Character::~Character()
{
// Crashes with Access Violation
//
delete m_abilityAttributes;
m_abilityAttributes = NULL;
delete m_primaryAttributes;
m_primaryAttributes = NULL;
}
在这一点上,我完全糊涂了——我不知道为什么析构函数会通过抽象接口再次被调用,而析构函数会CharacterDecorator
通过其具体实现被调用。此外,添加析构函数CharacterDecorator
似乎并不能解决问题。
作为参考,我已经包含了 的实现Player
和Character
接口CharacterDecorator
:
class CharacterDecorator : public Character
{
public:
virtual Armor* getArmor() const = 0;
virtual Weapon* getWeapon() const = 0;
};
Player
:
Player::Player()
{}
Player::Player(Character* player)
:m_player(player)
,m_weapon(0)
,m_armor(0)
{}
Player::Player(Character* player, Weapon* weapon, Armor* armor)
:m_player(player)
,m_weapon(weapon)
,m_armor(armor)
{}
Player::~Player()
{
delete m_armor;
delete m_weapon;
}
// getters
Armor* Player::getArmor() const
{
return m_armor;
}
Weapon* Player::getWeapon() const
{
return m_weapon;
}
// additional methods ...
Character
:
Character::Character()
{}
Character::Character(const Builder& builder)
:m_name(builder._name)
,m_description(builder._description)
,m_abilityAttributes(builder._abilityAttributes)
,m_primaryAttributes(builder._primaryAttributes)
{}
Character::Character(const Character& rhs)
{
m_name = rhs.m_name;
m_description = rhs.m_description;
m_abilityAttributes = new AbilityAttributes();
m_primaryAttributes = new PrimaryAttributes();
*m_abilityAttributes = *rhs.m_abilityAttributes;
*m_primaryAttributes = *rhs.m_primaryAttributes;
}
Character::~Character()
{
delete m_abilityAttributes;
m_abilityAttributes = NULL;
delete m_primaryAttributes;
m_primaryAttributes = NULL;
}
// additional methods ...
// Builder pattern methods
//
Character::Builder::Builder()
: _abilityAttributes(0), _primaryAttributes(0)
{}
Character* Character::Builder::build()
{
return new Character(*this);
}
Character::Builder& Character::Builder::abilityAttributes(AbilityAttributes* value)
{
_abilityAttributes = value;
return *this;
}
Character::Builder& Character::Builder::primaryAttributes(PrimaryAttributes* value)
{
_primaryAttributes = value;
return *this;
}