The Guest
The Guest

Reputation: 59

C++ Destructors and Ownership

I try to replicate C++ destructors and constructors in my c programming. That means for every object or struct there is an initialization function and a destruct function which frees all of the objects resources like so:

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);
}

The destruct function is called at the end of every function scope just like in c++ only that i put it manually there. So now in DestructMyObject function I call the destructors of every struct string type because for the struct string object i would also have a destruct function written just like for the struct MyObject Object.

Example with my problem:

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

     DestructMyObject(&Object1);

    return 0;
}

You see that i have transfered ownership of one Member of Object1 to another function but everything of Object1 will be destroyed by its destructor in the main function.

How do c++ destructors handle this kind of situation? I don't want that the destructor for struct string b is called at the end of main but it will be called because i call the destructor for MyObject. The function TransferOwnershipFunction(...) is now responsible for freeing the string object.

EDIT Somebody knows how a rust compiler would resolve this issue? So in Rust would i need to clone the struct string object I'm passing to TransferOwnershipFunction or is there another way of doing it because cloning (or copying i guees) seems to be a very expensive operation.

Upvotes: 2

Views: 198

Answers (1)

Sergey Aleksandrovich
Sergey Aleksandrovich

Reputation: 236

From my point of view main() should be responsible for creating and deleting of Object1. And TransferOwnershipFunction() should work with a copy of Object1.b. In this case:

  1. You need to create functions which work as analog of copy constructor and assignment operator (for C++03). Also move constructor and move assignment operator were added in C++11.
  2. In C++03 copy constructor and assignment operator are generated implicitly if you don't declare them. By default they copy objects by member of class (not by bytes in memory) using copy constructor of each member (except simple types like int, double...). So you need to imitate of passing Object1.b by value with calling of copy constructor: in TransferOwnershipFunction create new object of type struct string, copy content of it by member. If struct string contains a raw pointer as member and you call malloc for this member in struct string's constructor and free in destructor than in copy constructor of struct string you need to call malloc than copy all content from passed variable. Don't forget to call destructor at the end of TransferOwnershipFunction.
  3. According to RAII you need to call destructors in reverse order relation to order of creating objects (order of constructors).

Upvotes: 1

Related Questions