C ++ Разрушители и Собственность - PullRequest
2 голосов
/ 18 октября 2019

Я пытаюсь копировать деструкторы и конструкторы C ++ в моем c-программировании. Это означает, что для каждого объекта или структуры есть функция инициализации и функция уничтожения, которая освобождает все ресурсы объектов следующим образом:

struct MyObject {
      struct string a;
      struct string b;
      struct string c;
};

ConstructMyObject(struct MyObject *obj) {
     ConstructString(&obj->a);
     ConstructString(&obj->b);
     ConstructString(&obj->c);
}

DestructMyObject(struct MyObject *obj) {
     DestructString(&obj->a);
     DestructString(&obj->b);
     DestructString(&obj->c);
}

Функция уничтожения вызывается в конце каждой области действия функции, как вC ++ только то, что я положил его там вручную. Поэтому теперь в функции DestructMyObject я вызываю деструкторы каждого типа struct string, потому что для объекта struct string у меня также будет функция уничтожения, написанная так же, как для struct MyObject Object.

Пример с моей проблемой:

int main {
     struct MyObject Object1;
     ConstructMyObject(&Object1);
     ...
     ...
     ...
     TransferOwnershipFunction(Object1.b); /*takes a struct string object as argument*/
     ...
     ...
     ...

     DestructMyObject(&Object1);

    return 0;
}

Вы видите, что я передал право собственности на одного члена Object1 другой функции, но все элементы Object1 будут уничтожены его деструктором в функции main.

Как с ++ деструкторы справляются с такой ситуацией? Я не хочу, чтобы деструктор для struct string b вызывался в конце main, но он будет вызываться, потому что я вызываю деструктор для MyObject. Функция TransferOwnershipFunction(...) теперь отвечает за освобождение строкового объекта.

EDIT Кто-нибудь знает, как компилятор ржавчины решил бы эту проблему? Так что в Rust мне нужно клонировать объект struct string, который я передаю TransferOwnershipFunction, или есть другой способ сделать это, потому что клонирует (или копирует я гусь), кажется, очень дорогая операция.

1 Ответ

1 голос
/ 18 октября 2019

С моей точки зрения, main () должен отвечать за создание и удаление Object1. И TransferOwnershipFunction () должен работать с копией Object1.b. В этом случае:

  1. Вам необходимо создать функции, которые работают как аналог конструктора копирования и оператора присваивания (для C ++ 03). Также конструктор перемещения и оператор присваивания перемещения были добавлены в C ++ 11.
  2. В C ++ 03 конструктор копирования и оператор присваивания генерируется неявно, если вы не объявляете их. По умолчанию они копируют объекты по членам класса (а не по байтам в памяти), используя конструктор копирования каждого члена (кроме простых типов, таких как int, double ...). Поэтому вам нужно имитировать передачу значения Object1.b по значению с вызовом конструктор копирования : в TransferOwnershipFunction создать новый объект типа struct string, copy содержимое его по элементу. Если struct string содержит необработанный указатель в качестве члена, и вы вызываете malloc для этого члена в конструкторе struct string и free в деструкторе, чем в конструкторе копирования из struct string, вам нужно вызватьmalloc чем скопировать весь контент из переданной переменной. Не забудьте вызвать деструктор в конце TransferOwnershipFunction.
  3. Согласно RAII вам необходимо вызывать деструкторы в обратном порядке по отношению к порядку создания объектов (порядку конструкторов).
...