Home > Net >  How to create/destroy objects in "modern" C ?
How to create/destroy objects in "modern" C ?

Time:03-26

I am porting C# app into C linux app. I am confused with construction and destruction in "modern" (C 11 ?). I always thought you have to use new/delete but now it appears C recommendation is not to do so (is this correct or I read a wrong blog?).

What I have roughly (there are 6 subclasses of B and BRec atm):

class ARec : public BRec
class A : public B
. . .
class Factory
  BRec GetRecord(WrapperStruct s)
  {
    if(s.Type == 'A')
    {
      A* a = (A*)s.Data;
      auto rec = ARec((ushort)a->Num);
      rec.OtherField = a.OtherField;
      return rec;
    }
. . .
main

// separate pthread
void* Logger(void* arg) {

    int* thread_state = (int*)arg;

    auto f = Factory();

    WrapperStruct item;

    while (true)
    {
      q->try_dequeue(item);

      auto rec = f.GetRecord(item);
      auto bytes = f.GetBytes(rec);

      // write bytes to file ...

      delete bytes;

      if(*thread_state == -1)
        pthread_exit(0);
    }

Question - how does compiler would know when to delete s.Data in factory method? Same - rec if it was created in a class method and then crossed to other method (while in Logger)? Is there a simple guide how to manage variables' memory in C 11 ?

EDIT: s.Data contains ref to an object created in a 3rd party dll and can be of different types hence the s.Type field

CodePudding user response:

Smart pointers are the key.

 std::shared_ptr<Foo> foo = std::make_shared<Foo>();
 std::unique_ptr<Foo> bar = std::make_unique<Foo>();

Shared pointers can be copied. They do reference counting. When the reference count drops to zero, they'll delete their contents automatically.

Unique pointers can't be copied. They can be copied by reference. When the unique pointer goes out of reference, it frees the object for you.

So it works a lot like Java now.

 void notAMemoryLeak() {
      std::shared_ptr<Foo> foo = std::make_shared<Foo>();
 }

Other than that, you treat them like pointers. The syntax for their use at this point is identical, except you're passing smart pointers, not Foo *.

 void myFunct(std::unique_ptr<Foo> &foo) {
      cout << "Foo: " << foo->getName() << "\n";
 }

The make_shared and make_unique can take the same arguments as any of your Foo's constructors, so feel free to pass stuff.

I do one more thing:

 class Foo {
 public:
      typedef std::shared_ptr<Foo> Pointer;
      ...
 };

 Foo::Pointer foo = std::make_shared<Foo>();

Sometimes I also create static methods to make it even cleaner. This is stylistic and not necessary. Some people might fault me. But it's clean and easy to read.

  • Related