2

I'm new to C++ and I'm wondering what's the best way to reconstruct/reinitialize an object? My minimal code looks like this:

typedef boost::shared_ptr<Object> PObject;

int main()
{
    PObject SomeObject;

    SomeObject = PObject(new Object);
    // some code
    *SomeObject = Object();
}

I feel that's not the right way to do it. Could someone show me the best way to do it? I just want to know how to reconstruct/reinitialize an object. Thanks!

Mark B
  • 95,107
  • 10
  • 109
  • 188
Jacky Boen
  • 831
  • 1
  • 7
  • 10
  • 1
    Why would you want to do this? – Pubby Dec 20 '11 at 18:07
  • Since you are a beginner, if you have access to a modern compiler, you should look into `std::shared_ptr` and `std::unique_ptr`. – Alexandre C. Dec 20 '11 at 18:17
  • I'm making some kind of a Game object that contains information like the player, the scoreboard, a vector of Enemy objects, etc. I wanted to know if there's a one-line solution to just reinitialize the Game object so everything just gets restarted. (also, the objects contained in the Game are also using shared_ptr). – Jacky Boen Dec 20 '11 at 18:22
  • 2
    Changing the value of the object and resetting the smart pointer are two different things. – Kerrek SB Dec 20 '11 at 18:28
  • Er yeah, the title is a bit misleading. I guess it should be "resetting an object through smart pointer". Sorry about that. – Jacky Boen Dec 20 '11 at 18:33
  • I edited your subject line to your new suggested title – Mark B Dec 20 '11 at 18:44

4 Answers4

5

When using a shared_ptr, you can use the reset-method for this:

SomeObject.reset(new Object);

Or, the exception-safe alternative (which you should use for the initialization as well):

SomeObject = make_shared<Object>();

Both these statements make shared_ptr point to a newly created Object. Other shared_ptr that referred to the same object will not be affected. If this shared_ptr was the only one that pointed to the old object, it will be destroyed.

To illustrate:

shared_ptr<int> foo = make_shared<int>(23);
shared_ptr<int> bar = foo;
std::cout << *foo << ", " << *bar << std::endl; // prints "23, 23"

*foo = 42;
std::cout << *foo << ", " << *bar << std::endl; // prints "42, 42"

bar = make_shared<int>(23);
std::cout << *foo << ", " << *bar << std::endl; // prints "42, 23"
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
  • 1
    There is a difference between `reset` and assigning to the pointed to object. – pmr Dec 20 '11 at 18:14
  • Indeed there is. My answer reflects what I think the OPs actual intention was. – Björn Pollex Dec 20 '11 at 18:44
  • What if I want every shared_ptr to point to the same object? How should I do that? Also, is it possible to call reset within the class itself? Because then, I can write a function for that class to reset itself and its object members (which are also using shared_ptr). Thanks a bunch, I think I'm on a progress of solving my problem. – Jacky Boen Dec 20 '11 at 19:10
  • You can of course simply write `reset`-method for all your classes and then call that. As for all pointers pointing to the same object, I am not sure what you mean by that. Maybe you want a [singleton](http://stackoverflow.com/questions/1008019/c-singleton-design-pattern) - you should try to avoid that though. – Björn Pollex Dec 20 '11 at 19:22
  • You said "Both these statements make shared_ptr point to a newly created Object. Other shared_ptr that referred to the same object will not be affected". What if I want all shared_ptr(s) to always point to the same object? (If one shared_ptr points to a new object, the rest will follow and point to that new object). Is it feasible? I want them to be synchronized and not independent. – Jacky Boen Dec 20 '11 at 19:38
  • To achieve that, you have to create one `shared_ptr` as in the first line of my example, and all the rest of them as in the second line of my example. – Björn Pollex Dec 20 '11 at 20:14
2

What do you actually want to do?

  • If you want to delete the old object and create a new object from scratch, pointed to by the same pointer, you can just do SomeObject = new Object. If you prefer, you can explicitly reset the shared pointer to make it clear the old object is deleted.
  • If you want to reset the contents of the object without deallocating it and reallocating it, then, provided it has a correctly-implemented assignment operator[1], your idiom of assigning a default-constructed object to it will work *PObject = Object()

[1] Warning: This is non-trivial if the object members are themselves smart pointers, the compiler generated assignemnt operator doesn't usually do what you want. It will create a "shallow" copy: two objects, but all their smart pointers will point to the same objects, which means if one changes, the other will also change.

Probably the best is to write your object with a "reset" function which sets all the fields to a clean state, and then (a) use that function in the constructor and (b) call that function in this point. If you don't want to do that, creating a new game object is more likely to be what you want, but either way could be correct, and even though they're very different conceptually, either may work here.

Jack V.
  • 1,381
  • 6
  • 20
0

It depends on what you actually want to achieve. The code you are showing will change the value pointed to through the shared_ptr for all clients. If that is what you want to do, your way is good.

If you want to get a new object for one client. shared_ptr::reset is the right way to do it.

However, in C++, values are generally preferred over shared objects. Unless there is a good reason to actually use the free store, don't do it.

pmr
  • 58,701
  • 10
  • 113
  • 156
  • That's right, I just want to reinitialize all the variables in SomeObject. My other objects also need to access that same SomeObject so they can perform different things based on the information in SomeObject. Is that a good reason or is there a better solution? Also, what do you mean by 'free store'? Thanks a bunch! – Jacky Boen Dec 20 '11 at 18:43
0

What you are doing is the correct thing if you want to reinitialize the object. You are calling the assignment operator on the original object pointed to by SomeObject with a temporary Object created with the default constructor.

Edward Strange
  • 40,307
  • 7
  • 73
  • 125