2

I'm not a C++ programmer, and I have great respect for its complexity, so I'd normally stay away from it. Despite this, I've found a certain library I'd like to tinker with.

The library includes a sample snippet where a single instance is allocated in local scope:

    Foo foo(arg1, arg2, ...);

I want to modify this example to re-initialize the object and do more things with it, but I can't do it via getters/setters or public variables. Is this possible without creating more instances?

In case there's no way of doing that without creating new instances, how could I release the memory of the objects I no longer need?

For instance, if it were a dynamic object, I guess it would be something like this:

    Foo* pfoo;

    pfoo = new Foo(arg1, arg2, ...);
    pfoo->doSomething();
    delete pfoo;

    pfoo = new Foo(arg3, arg4, ...);
    pfoo->doSomething();
    delete pfoo;

What would be the equivalent for the object allocated in the stack?

Mister Smith
  • 27,417
  • 21
  • 110
  • 193
  • 2
    What do you mean by "re-initialize" the object? I would assume you mean call the constructor again, but then you mention something about getters/setters. Is this a possible duplicate of [Calling a constructor to re-initialize object](http://stackoverflow.com/questions/2166099/calling-a-constructor-to-re-initialize-object)? – Daniel May 15 '14 at 16:35
  • 3
    Your two choices are either setters/getters or making a brand new object. Since you said you are unable to use the former, then you must make a new object `Foo foo2(arg3, arg4, ..)` – Cory Kramer May 15 '14 at 16:36
  • The c++ way is that one object does one thing. Can't you just create two objects? – Richard Hodges May 15 '14 at 16:53
  • 1
    @MisterSmith: Your second example is usually bad style. You don't "reuse" pointers like this in C++. You just create a second pointer, unless you develop your software in an extremely special environment or with very unwieldy legacy code. – Christian Hackl May 15 '14 at 16:57

3 Answers3

9

The only way to release automatic variables is to let them fall out of scope:

void bar() {
  Foo f1(arg1, arg2);
  f1.doSomething();

  {
    Foo f2(arg3, arg4);
    f2.doSomething();
    // other stuff ...
    // f2 dies here.
  }

  {
    Foo f3(arg5, arg6); // allocated on stack, possibly overlapping f2's old spot
    f3.doSomething();
    // ...
    // f3 dies here.
  }

  // f1 dies here.
}
Jeff
  • 3,475
  • 4
  • 26
  • 35
  • 1
    Not the _only_ way. You can use placement new - `Foo f(arg3, arg4); f.~Foo(); new(&f) Foo(arg5, arg6);` – Captain Obvlious May 15 '14 at 16:46
  • OK, placement `new` works too, but that's more insane than goofy for vanilla automatic objects. :) And to be fair, I said *release*, which your example still requires of `f` eventually. – Jeff May 15 '14 at 16:49
2

If an object doesn't allow to reinitialize itself via public setters - you can not do it.

Actually, in your example you are not reinitializing object, you create another instance of Foo and reinitialize a pointer variable with address of this object.

Lifetime of local variable is limited to their scope. So you can split the scope of your function into smaller scopes:

void bar()
{
  {
    Foo foo(arg1, arg2, ...);
    foo.doSomething();
  }
  {
    Foo foo(arg3, arg4, ...);
    foo.doSomething();
  }
}
nevermind
  • 2,300
  • 1
  • 20
  • 36
2

Just wanted to post one more alternative for the OP, more along the lines of what he has suggested:

void somefunction()
{
    // create the first foo owned by a smart pointer
    std::unique_ptr<Foo> pFoo { new Foo { arg1, arg2, ... } };
    pFoo->doSomething();

    // now replace the old Foo with a new one
    pFoo.reset( new Foo { arg3, arg3, ... } );
    pFoo->doSomething();

    // no need to delete anything unless you specifically want the Foo to die now
    // in which case...
    // pFoo.reset();
} // implicit destruction of whatever pFoo owns happens here
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142