Reputation: 16815
I have a union-like class with a member that may or may not be garbage depending on a boolean flag also set in that same class.
Obviously, I do not want that garbage to be destructed when my class goes out of scope. How to prevent a class member from being destructed?
I know this could be achieved with pointers and dynamically allocated memory, but I am looking for a more simple solution.
class MyContainer {
bool has_child;
MyChild child;
public:
MyContainer(MyChild child) { this->has_child = true; this->child = child; }
MyContainer() { this->has_child = false; }
~MyContainer() {
if (!this->has_child) {
// What to do here?
}
}
}
Upvotes: 4
Views: 341
Reputation: 50540
I'm not that sure I would recommend it, but you can use placement new in a correctly sized array to do that.
As a minimal, working example:
#include<iostream>
struct MyChild {
~MyChild() { std::cout << "destructor" << std::endl; }
};
class MyContainer {
bool drop;
char arr[sizeof(MyChild)];
MyChild *child;
public:
MyContainer(bool drop)
: drop{drop}, child{::new(&arr) MyChild{}}
{}
~MyContainer() {
if (drop) { child->~MyChild(); }
}
};
void f() {
std::cout << "f" << std::endl;
MyContainer cont{true};
}
void g() {
std::cout << "g" << std::endl;
MyContainer cont{false};
}
int main() {
f();
g();
}
As you can see, destructor of MyChild
is called only within f
. Within MyContainer
, whenever you want to access the instance of MyChild
, you can do that through the child
data member. And, of course, it's not dynamically allocated.
Upvotes: 2
Reputation: 172894
You can use std::optional (since C++17), which won't cause dynamic memory allocation. e.g.
class MyContainer {
bool has_child;
std::optional<MyChild> child;
public:
MyContainer(MyChild child) : child(child) { this->has_child = true; }
MyContainer() { this->has_child = false; }
~MyContainer() { /* nothing special need to do */ }
};
BTW: The member has_child
could be replaced by std::optional::has_value()
.
Upvotes: 5