Search code examples
c++pointerssmart-pointers

How to store pointers to objects that class doesn't own?


I am trying to code two classes FooFactory and Foo. FooFactory initializes an object ToolBox in the constructor and stores it in a unique_ptr as I want that to be cleaned after the factory is destructed. All the instances of Foo should be able to use ToolBox so I am passing ptr to ToolBox object in the constructor of Foo and storing it as bare ptr.

I am new to c++ development so, my questions in the light of general suggestion I heard :

avoid raw pointers when possible

  1. Is the usage of bare ptr to store the tool_box object that Foo doesn't own fine in this case? or Can I do better using smart_ptr?
  2. Is the pattern of passing the ptr to ToolBox from the FooFactory class to every new object the correct or is there something better I can do?

Pseudo-code for my classes:

class FooFactory {
 public:
  FooFactory() {
    tool_box_.reset(new ToolBox());
  }

  std::unique_ptr<Foo> NewFoo() {
    std::unique_ptr<Foo> foo(new Foo(tool_box_.get());
    return foo;
  }
  std::unique_ptr<ToolBox> tool_box_;
}

class Foo {
 public:
  Foo(ToolBox* tool_box) {
    tool_box_ = tool_box;
  }
 private:
  // Not Owned
  ToolBox* tool_box;
}

Solution

  • A factory would normally never control the lifetime of an object. It should hand out an appropriate pointer, preferably a std::unique_ptr and the caller determines it's lifetime.

    #include <string>
    #include <iostream>
    #include <memory>
    
    class Box
    {
    public:
        Box() {}
    };
    
    class Foo
    {
    public:
        Foo(std::shared_ptr<Box> &box)
        : m_box(box)
        {
        }
        virtual ~Foo(){}
    
        void print()
        {
            std::cout << "Hello World" << std::endl;
        }
    
    protected:
        Box *getBox()
        {
            return m_box.get();
        }
    
    private:
        std::shared_ptr<Box> m_box;
    };
    
    class FooFactory
    {
    public:
        FooFactory()
        {
            m_box = std:make_shared<Box>();
        }
    
        std::unique_ptr<Foo> CreateFoo()
        {
            return std::make_unique<Foo>(m_box);
        }
    
    private:
        std::shared_ptr<Box> m_box;
    };
    
    int main()
    {
        FooFactory factory;
        std::unique_ptr<Foo> foo = factory.CreateFoo();
    
        foo->print();
    
        return 0;
    }