I have this simple piece of code (Command pattern) that doesn't work as expected.
Usually a polymorphic type would work when it's manipulated by either a pointer or a reference. So if Command
is an interface and m_command
is a reference, then SetCommand
should work for different concrete types of Command
(eg, CommandLightOn
and CommandGarageDoorOpen
) ? It turns out not the case. Once SimpleRemote
is instantiated with CommandLightOn
, the SetCommand
has completely no effect. In this example, attempt to change the underlying object to CommandGarageDoorOpen
has no errors, but no effect either.
It works fine if m_command
in SimpleRemote
is changed to pointer type. So the question is why reference type fails to work in this case?
class SimpleRemote
{
public:
SimpleRemote( Command& command ) : m_command{ command } {}
void SetCommand( Command& command )
{
m_command = command; //<-- broken
}
void ButtonPressed()
{
m_command.execute();
}
private:
Command& m_command;
};
Output:
Light is on
Light is on #<-- expect that it prints "Garage door is up"
Full code of this example (simple Command pattern):
#include <iostream>
using std::cout;
class Light
{
public:
void On()
{
cout << "Light is on\n";
}
private:
};
class GarageDoor
{
public:
void Up()
{
cout << "Garage door is up\n";
}
private:
};
// the Command interface
class Command
{
public:
virtual void execute() = 0;
};
class CommandLightOn : public Command
{
public:
CommandLightOn( Light light ) : m_light{ light }{}
void execute() override
{
m_light.On();
}
private:
Light m_light;
};
class CommandGarageDoorOpen : public Command
{
public:
CommandGarageDoorOpen( GarageDoor door ) : m_door{door} {}
void execute() override
{
m_door.Up();
}
private:
GarageDoor m_door;
};
class SimpleRemote
{
public:
SimpleRemote( Command& command ) : m_command{ command } {}
void SetCommand( Command& command )
{
m_command = command;
}
void ButtonPressed()
{
m_command.execute();
}
private:
Command& m_command;
};
int main()
{
Light light;
CommandLightOn light_on( light );
SimpleRemote remote( light_on );
remote.ButtonPressed();
GarageDoor door;
CommandGarageDoorOpen door_open( door );
remote.SetCommand( door_open );
remote.ButtonPressed();
}
Aucun commentaire:
Enregistrer un commentaire