简体   繁体   中英

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)

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM