Can I terminate the scope of a C++ variable without ending a block?
I would like to do something like the following pattern:
T* const pT = findT();
// Do some work
T* const pT2 =开发者_开发问答 new T( *pT );
// Mutate the object pT2 refers to
delete pT;
// At this point, I want the scope of pT to end.
// I do not want the scope of pT2 to end
I know I can end scope by ending a block, but it ends up like this:
T* pT2 = 0;
{
T* const pT = findT();
// Do some work
pT2 = new T( *pT );
// Mutate the object pT2 refers to
delete pT;
}
This causes pT2 to lose its const qualifier because I have to assign to it after it's declared.
I want my cake and I'd like to eat it too, I want clear constness and proper scoping!
Is there any way to end scope on a variable other than by ending a block? If not, are there any plans to extend the standard to support this?
You can use lambdas:
T* const pT = []() -> T* {
T* pT;
// Do whatever the hell you want with pT
return pT;
}();
Is there any way to end scope on a variable other than by ending a block?
No. The scope of a local variable begins when it is declared and ends at the end of the block at which it is declared.
If not, are there any plans to extend the standard to support this?
This sounds like a really bad idea: this would add unnecessary complexity to rules concerning scope, name lookup, and object lifetime.
What you call "block" is another name in C++ for "scope". This is how you define a scope in C++.
Another option here is to use a std::auto_ptr
, which transfers ownership on assignment. The old pointer won't clean up but will effectively be nil.
No. You can however use the following idiom to beautify your example somewhat (okay, that's subjective, but hey):
T* p1 = 0;
if (T* const p2 = findT()) {
p1 = new T( *p2 );
delete p2;
}
You can use std::optional (or boost::optional) for a fine grained control on object life-time.
Here is an example:
std::optional< ClassA > a(std::in_place, 1); // ClassA constructor is called
std::optional< ClassB > b(std::in_place, 2); // ClassB constructor is called
a.reset(); // ClassA destructor is called
b.reset(); // ClassB destructor is called
Unfortunately, the name of the variable is still there and its memory is still allocated.
There is also a trick to destroy a string and free its memory (the variable itself is still there):
std::string my_str;
std::string{}.swap(my_str); // likely to free the memory
It's implementation defined, so it may actually not free the memory, but it is likely to do so.
精彩评论