Steven Lu
Steven Lu

Reputation: 43547

Using manual memory management with a reference?

I have a variable which is referenced a lot. It started out as an automatic variable.

Now I decided that in the middle of some code I want to call its dtor to reset its state, so I intend to deallocate and reallocate it. The standard way to do this of course is to call delete on it and make a new one.

Before:

void func() {
    ClassName varname; 
    while (varname.check()/*...*/) { if (varname.function()/*...*/) { /* bunches of code ... */
            /*... some more code ... */ 
        }
    } 
}

Now I want:

void func() {
    ClassName varname; 
    while (varname.check()/*...*/) { if (varname.function()/*...*/) { /* bunches of code ... */
            if (key_code[SDLK_r]) { // Pressing R key should reset "varname"!
                /* Here I want to dealloc and realloc varname! */
                /* But if I declare varname as a ptr on line 2, */
                /* line 3 (rest of code) must be refactored. */
            }
        }
    } 
}

My first attempt is to go change line 2 to be something like this

ClassName *varnamep = new ClassName();
ClassName& varname = *varnamep;

But I'm not sure if that means I'll be able to call delete on it later and reassign the reference!

                delete &varname; 
                varnamep = new ClassName();
                varname = *varnamep; // I assume compiler will error here because I can't reassign a ref. 

Can I do this some other way? Or should I just suck it up and do a find-replace for turning varname. into varname->? In this particular case for my actual real situation I will probably implement a member function reset() and not worry about this actual problem. But I would like to know if there is some shortcut to being able to effectively treat references as pointers (or it could turn out that this is absurd nonsense)

Upvotes: 1

Views: 85

Answers (2)

rob mayoff
rob mayoff

Reputation: 386018

Given ClassName varname, you could do this:

varname.~ClassName();
new (&varname) ClassName;

But I wouldn't recommend it. This uses two less-commonly-known features of C++: an explicit destructor call, and placement new. Only use this if it makes a significant difference in performance, as measured by your profiler, and the ClassName constructor can't throw an exception.

If ClassName::operator= does what you need (or you can modify it to do what you need), you can do this:

varname = ClassName();

That is more easily understood than using an explicit destructor call followed by placement-new.

Another common idiom:

varname.swap(ClassName());

This works if ClassName has an efficient swap method, like standard containers do. This is subtle enough that it probably deserves a comment if you decide to use it.

Upvotes: 4

juanchopanza
juanchopanza

Reputation: 227588

The standard way is not to delete and create a new instance. Just reassign the variable:

ClassName varname = .... ;

....

if (some condition) {
  varname = SomethingElse;
}

and make sure that the copy constructor, assignment operator and destructor correctly deal with resources managed by ClassName.

Upvotes: 2

Related Questions