I guess you could describe it as c++98's version of c++11 auto variables. So that's a poor c++98 use case.
O_o
Well, yeah, you could, but you would be greatly exaggerating the utility.
I am in the sense that a non virtual destructor is called, and all that's declared is a reference to the base class.
No. You are not in any sense.
The destructor would still be called even without the reference; you may as well argue you could call a non-virtual destructor via a completely unrelated reference because that would still work:
Code:
#include <iostream>
struct Bar{
};
struct Foo: Bar {
~Foo(){std::cout<<"dtor\n"<<std::flush;}
};
const Foo * Awful
(
const Foo & f
)
{
return(&f);
}
int main(){
const unsigned int & x(*reinterpret_cast<const unsigned int *>(Awful(Foo())));
return 0;
}
The `Foo' object is still destroyed correctly, but I am not, in any way, calling the destructor for the anonymous `Foo' object more or less than the example code you posted.
Of course, the lifetime of the anonymous object isn't changed, but then, the introduction of the call changes how the compiler perceives the expected lifetime in any event:
Code:
#include <iostream>
struct Bar{
};
struct Foo: Bar {
~Foo(){std::cout<<"dtor\n"<<std::flush;}
};
void do_stuff(){
std::cout << "do stuff\n";
}
const Bar & Awful
(
const Foo & f
)
{
return(f);
}
int main(){
const Bar & example( Awful( Foo() ) );
do_stuff();
return 0;
}
You correctly describe the reason why this works, but the result is what it is -- there is no explicit base object reference, and the code needs inheritance to work.
Well, yes, there is an explicit base object reference, and while there is no explicit derived object reference, the inheritance is unimportant. In fact, you've only confused things by introducing inheritance:
Code:
#include <iostream>
struct Bar{
};
struct Foo {
~Foo(){std::cout<<"dtor\n"<<std::flush;}
};
const Foo & Awful
(
const Foo & f
)
{
return(f);
}
int main(){
const Bar & x(reinterpret_cast<const Bar &>(Awful(Foo())));
return 0;
}
Here again the `Foo' temporary is destroyed correctly, but that fact is completely unrelated to the named reference.
The named reference from the correct and valid code does two things: names the temporary and tells the compiler to extend the lifetime of the object to that of the reference.
The very notion of "calling a non-virtual destructor via a reference to the base class" is dangerous, and you are not doing that, and you should not do that because it doesn't work:
Code:
#include <iostream>
struct Bar{
};
struct Foo: Bar {
~Foo(){std::cout<<"dtor\n"<<std::flush;}
};
int main(){
Bar * example(new Foo);
delete example;
return 0;
}
The mechanism here is broken, and the mechanism would still be broken if the compiler approached the anonymous temporary as if by reference to the base class which it does not do because you are only naming the temporary that compiler would have already managed.
Soma