Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using smart pointers as a class member

I have been reading up on smart pointers and recently in class my TA said that we should never use raw pointers. Now, I've done a lot of reading online and looked at different questions on this website but I'm still confused on some aspects of smart pointers. My question is: which smart pointer would I use if I want it to be used across my program? I'll show some code.

So I have a basic Application class that makes declarations of objects from class AI. Note: I have two different smart pointers, a unique one and a shared one, for testing reasons.

// Application class in Application.h

class Application
{
public:
    Application(){}
    ~Application(){}

    //... additional non-important variables and such

    unique_ptr<AI> *u_AI; // AI object using a unique pointer
    shared_ptr<AI> *s_AI; // AI object using a shared pointer

    //... additional non-important variables and such

    void init();
    void update();
};

// AI class in AI.h

class AI
{
public:
    AI(){}
    ~AI(){}

    bool isGoingFirst;
};

In the Application init function, I want to create the AI object, and then I want to use it in the update function. I am not sure if I am declaring my pointer right at all, but I know for a fact that it compiles and it works for assigning and printing out data in the init function. More code below.

void Application::init()
{
    //.. other initialization's.

    std::shared_ptr<AI> temp(new AI());
    sh_AI = &temp;
    sh_AI->isGoingFirst = true;

    //.. other initialization's.
    // Function ends.
}

void Application::update()
{
    if(sh_AI->get()->isGoingFirst == true)
    {
         // Do something
    }
    else
    {
        // Do something else
    }

    // Other code below
}

Later in my program, the update function is called, which uses the same AI smart pointer that I declared in my class Application. What I have found out is that the smart pointer AI object is being deleted. I understand that smart pointers have automatic memory management, but is there a smart pointer that will allow you to use a it in different functions without creating any major problems, such as memory leaks or dangling references? Or am I missing the whole point of smart pointers?

I'm sorry if this was answered in another question but I read into a lot of the other questions, and while I understand more about smart pointers, I'm still learning. Thank you!

like image 677
Wes Avatar asked Jun 12 '26 22:06

Wes


1 Answers

As Neil Kirk pointed out in the comments, these declarations are not what you want:

unique_ptr<AI> *u_AI; // AI object using a unique pointer
shared_ptr<AI> *s_AI; // AI object using a shared pointer

u_AI and s_AI are still objects to raw pointers. The whole point is to remove the need to manage the raw pointer directly. So now you replace them with:

unique_ptr<AI> u_AI; // AI object using a unique pointer
shared_ptr<AI> s_AI; // AI object using a shared pointer

to assign your created pointer, you use the function make_unique or make_shared:

u_AI = unique_ptr<AI>(new AI()); // Yu may be able to use make_unique like 
                                 // make_shared but it's new to C++14. may not be available
s_AI = make_shared<AI>();

Then, when you need to access them, you just pretend they are pointers, so in your update function:

if(sh_AI->get()->isGoingFirst == true)

becomes:

if(sh_AI->isGoingFirst == true)

As for when to use unique_ptr vs shared_ptr, you answer that by answering the following question: What do I want to happen when someone makes a copy of Application? i.e.:

Application app1;
app1.init();
Application app2 = app1; // ?? what happens to AI object in app2?

There are 3 possible answers:

  1. I want there to be an extra copy of AI in app2. In this case you use unique_ptr and make sure you implement a copy constructor that does the copying.
  2. I want app2 and app1 to share a copy of AI. In this case you use shared_ptr and the default copy constructor will do the job for you.
  3. I don't want there ever to be a copy of Application. (Which makes sense for a class called Application). In this case it doesn't really matter (in which case I would default to unique_ptr) and remove the copy constructor:

    Application(const Application&) = delete;

like image 138
zdan Avatar answered Jun 14 '26 13:06

zdan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!