Оставьте поле члена класса неинициализированным - PullRequest
1 голос
/ 03 августа 2020

Я ищу механизм на 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, если я использую второй конструктор?

...