Я ищу механизм на C ++, который позволил бы классу не безоговорочно уничтожать одно из своих полей-членов, а вместо этого требовало бы явного уничтожения. Другими словами, неуправляемый класс std :: optional.
Я придумал следующее:
template <typename T>
struct Node {
// ... a bunch of stuff ...
Node* parent; // not related to data
union {
bool _dummy;
T data;
};
Node() : parent(nullptr) {}
Node(Node* p, T data) : parent(p), data(std::move(data)) {}
~Node() {
// my invariant is: data is initialized iff parent is not nullptr
if (parent) data.~T(); // data leaks if this is commented out
}
};
int main() {
std::string text = "abcdefghijklmnopqrstuvwxyz";
Node<std::string> a;
Node<std::string> b(&a, text);
return 0;
// no memory leak
}
Использование std::optional<T>
здесь будет излишним и сделает Node<T>
больше. Использование указателя также не вариант.
Есть ли лучший вариант, который не требует дополнительного места? Если нет, имеет ли уродливое объединение правильную семантику инициализации data
, если я использую второй конструктор?