Reputation: 43547
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
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
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