mathworker
mathworker

Reputation: 181

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;
}

Upvotes: 1

Views: 431

Answers (2)

Devolus
Devolus

Reputation: 22084

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;
}

Upvotes: 3

aquastan
aquastan

Reputation: 21

One way to store a non-owning "pointer" to an object (while coupling the class with that object) would be to store a reference (or perhaps a const reference) instead of a pointer.

In my experience, the constraint of needing to initialize the class with that reference helps hierarchical design and simplifies lifetime management.

Upvotes: 2

Related Questions