I found this code on cppreference.com. It's the strangest C++ I've seen, and I have a few questions about it:
union S
{
std::string str;
std::vector<int> vec;
~S() {}
};
int main()
{
S s = { "Hello, world" };
// at this point, reading from s.vec is undefined behavior
std::cout << "s.str = " << s.str << '\n';
s.str.~basic_string<char>();
new (&s.vec) std::vector<int>;
// now, s.vec is the active member of the union
s.vec.push_back(10);
std::cout << s.vec.size() << '\n';
s.vec.~vector<int>();
}
I want to make sure I've got a few things right.
- The union forces you to initialise one of the union members by deleting the default constructors, in this case he initialised the string with Hello World.
- After he's initialised the string, the vector technically doesn't exist yet? I can access it, but it isn't constructed yet?
- He explicitly destroys the string object by calling its destructor. In this case when S goes out of scope, will the ~S() destructor be called? If so, on which object? If he doesn't call the destructor explicitly on the string is it a memory leak? I'm leaning towards no because strings clean themselves up, but for unions I don't know. He calls the destructor for both the string and vector himself, so the ~S() destructor seems useless, but when I delete it my compiler won't let me compile it.
- This is the first time I've seen someone use the new operator to place an object on the stack. In this case is this the only way now that the vector can be used?
- When you use placement new as he does with the vector, you're not supposed to call delete on it because new memory hasn't been allocated. Usually if you placement new on the heap you have to free() the memory to avoid a leak, but in this case what happens if he let's the vector and union go out of scope without calling the destructor?
I find this really confusing.
union
with a destructor before. Good, bad, I dunno. Just never seen one. – Caliphnew
can be cleanly separated out. It shouldn't be in the question – Gregoriogregorius