开发者

Singleton class whose ctor requires arguments

开发者 https://www.devze.com 2023-01-30 17:52 出处:网络
I have class Command which is an instance of a class EventManager. Class Command requires two arguments(host, target) in its constructor.

I have class Command which is an instance of a class EventManager. Class Command requires two arguments(host, target) in its constructor.

class EventManager
{
public:
   void Event1(){ cmd->Execute(_eventEnum); }
private:
   Command *cmd;
};

class Command
{
public:
   Command(Host h, Target t)
   void Execute();
private:

}

Now if i need to use th开发者_如何学运维is method cmd->Execute() in a member function of Target class, i need to make cmd an instance variable of Target or make it global as a singleton.

I cant make cmd an instance variable of Target because it doesn't take host instance. To make it a singleton would be to add two methods like this

class Command
{
public:

   CreateInstance(Host h, Target t);
   GetInstance(); 
   void Execute();
private:
   Command(Host h, Target t);

}

I need to make sure that GetInstance is called after CreateInstance. Any other alternative?

Target class is a low level class with few events.

Target::LowlevelEvent()
{
 cmd->Execute(lowlevelevent) //In Execute for lowlevelevent in Command class, i might call target->reset
}

Iam sorry for not being able to explain clearly. The problem is, this code has lot of events(methods), which may be in classes like EventManager or Target.

In each of these event, i would have to call a Command->Execute(). The command class requires host and target instances because they can do certain actions.

EventManager::Event1() { cmd->Execute(_event1); }

Target::Event2() { cmd->Execute(_event2); }

Command::Execute(Events e) { if (_event1 == e ) { host->CallAction(); } if (_event2 == e) { target->CallSomeOtherAction(); }

}

So now cmd needs to be an instance variable of both EventManager and Target right? Now EventManager has host and target instance which can be passed to Command ctor.

But Target doesn't have access to host. So i cant create Command instance in Target class.

So i was wondering if i create the singleton in EventManager ctor. And then call GetInstance() in Target. I know its bad idea but with this huge design, iam not able to figure out. Thanks for your help.


I really do not understand your problem, but, just from the title, I can say this: Don't use a singleton. The fact that it requires arguments is a pretty good counter-indicator for the singleton pattern.

If you want to make sure that all commands are created with the same parameters, you can provide the client with a CommandFactory that creates instances of commands.

class CommandFactory {
public:
    CommandFactory(std::string host, std::string target)
        : m_host(host),
          m_target(target)
    {}

    boost::shared_ptr<Command> createCommand() {
        return boost::shared_ptr<Command>(new Command(m_host, m_target));
    }
private:
    std::string m_host;
    std::string m_target;
};

Then you could also implement some kind of object pool to reuse objects.


There is absolutely no need to make Command a singleton. Just instantiate one as you need it with the proper parameters, pass it to the manager, use it and get rid of it. You probably want to pass it, so it is a good idea to use a shared_ptr.

0

精彩评论

暂无评论...
验证码 换一张
取 消