Using interface in C++ for dependency injection

2019-02-26 07:29发布

Assume I have the following abstract class and use it as an "interface" in C++:

class IDemo
{
  public:
    virtual ~IDemo() {}
    virtual void Start() = 0;
};


class MyDemo : IDemo
{
  public:
    virtual void start()
    {
      //do stuff
    }
};

Then in the class that need to have a handle to the interface (concrete class through injection):

class Project
{
  public:
    Project(IDemo demo);

  private:
    IDemo *_demo;
};

My intention is to assign concrete Demo class through the constructor of Project. This code doesn't compile since IDemo can't be instantiated. Any suggestions? Thanks in advance.

5条回答
狗以群分
2楼-- · 2019-02-26 07:56

It depends. If the concrete Demo object is not owned by Project, use a reference:

class Project
{
    public:
        Project(IDemo &demo);
    private:
        IDemo &_demo;
};

If you want ownership, use a boost::shared_ptr:

class Project
{
    public:
        Project(boost::shared_ptr<IDemo> demo);
    private:
        boost::shared_ptr<IDemo> _demo;
};

Project project(boost::make_shared<Demo>());

In C++0x you can also use an std::unique_ptr, if you do not want shared ownership.

查看更多
萌系小妹纸
3楼-- · 2019-02-26 07:59

Try:

 Project::Project(IDemo* demo)
     : _demo(demo)
 {}

But If the demo object is never going to change for the lifetime of the project then I prefer to pass by reference:

class Project
{
    public:
        Project(IDemo& d)
          : demo(d)
        {}
    private:
        IDemo&  demo;
};

Then use it like this:

int main()
{
    MyDemo    demo;
    Project   project(demo);
}
查看更多
疯言疯语
4楼-- · 2019-02-26 08:07

Must be:

class IDemo
{
    public:
        virtual ~IDemo() {}
        virtual void Start() = 0;
};


class MyDemo : public IDemo
{
    public:
        virtual void Start()
        {
            //do stuff
        }
};

...............................

class Project
{
    public:
        Project(IDemo* demo);
    private:
        IDemo *_demo;
};

Note

(1) class MyDemo : public IDemo

(2) IDemo* demo already suggested earlier (or you may also use IDemo& demo but it is conventional to use pointer to interface).

(3) virtual void Start() {...} instead of start (identifiers are case-sensitive).

查看更多
Animai°情兽
5楼-- · 2019-02-26 08:14
Project(IDemo demo);

Should be

Project(IDemo *demo);
查看更多
来,给爷笑一个
6楼-- · 2019-02-26 08:18

Without seeing the exact compiler warning I suggest you change

Project(IDemo demo);

To

Project(IDemo *demo);
查看更多
登录 后发表回答