Errors, bugs, questions - page 1951

 
Stanislav Korotky:

Is there any way to return an anonymous object instance from a function?

Replace it with a macro.
 
fxsaber:
Replace it with a macro.

It won't work. This is a class method and param is actually taken from the object. I have simplified it here for example.

 
Stanislav Korotky:

It won't work. This is a class method and param is actually taken from the object. I have simplified it here for example.

You'd better familiarize yourself with the original task, of course...

Would it be wrong to return a pointer?

 

Stanislav Korotky:

It works, except that it creates an extra internal copy, andthe return statement requires a copy constructor in the class. Although the copy is nailed when the function exits, I would like to eliminate the copying itself.


Class function()
{
  int param = 0;
  Class obj(param);
  return obj;
}

Of course it does, the local variable is destroyed when the function exits.
Use new and return the pointer, what's the problem?

If you need resource control, use a wrapper like smart pointer.
Maybe you could use something from Creational Patterns like singleton or builder...

 
fxsaber:

Better, of course, to familiarise yourself with the original task...

Would it be wrong to return the pointer?

That was originally on pointers. But then the client code is responsible for removing them, and that's a lot of rubbish, not to mention the fact that it takes a blink of an eye and you're left with suspended links.

 
Sergey Dzyublik:

Of course it does, after exiting the function the local variable is destroyed.

Use new and return a pointer, what's the problem?

If you need resource control, use a wrapper like smart pointer.
Maybe something from Creational Patterns like singleton or builder will work for you.

Pointers are there - inconvenient (answered above). I've tried looking towards "smarts". But my impression is that for MQL a smart pointer will only give another level of referentiality, which will need to be monitored in turn. After all, what is a smart pointer? - It's a wrapper object in which the initial reference is placed. And who and when will clean the wrapper? ;-) If you have ready solutions, please drop me a line. I have a test case for now.

 
Stanislav Korotky:

After all, what is a smart pointer? - It is a wrapper object in which the original reference is placed. And who and when will clean the wrapper? ;-) If you have ready solutions, please drop me a line. I have a test-case for now.


Use shared_ptr.
You don't need to clean this wrapper, you just copy it and shared_ptr is how many instances of desired resource are left and when to release this or that resource.


There are no ready-made solutions, at least for me. Adapt C++ ones.

 
Sergey Dzyublik:

There are no ready-made solutions, at least not for me. Adapt the C++ ones.

It's understandable - that's what I'm doing, but I already have the impression that MQL won't allow to make "tracing".

 
Stanislav Korotky:

Is there any way to return an anonymous object instance from a function?

As someone has already pointed out here, the most correct way is to return a smart pointer from a function. All this is implemented in MQL. Although it's not as convenient to use as in C++, because pass by pointer should be implemented via method, rather than via pass operator. By the way, for the task at hand I suppose shared_ptr is not necessary, unique_ptr will be enough.

Alternatively, the created pointer inside the function could be immediately placed in some global array, which would be trashed at the end of the program. At the same time, the user can free the object's memory at any moment by calling a special function (not delete). It's like CloseHandle in WinApi.

It works, except that an extra internal copy is created and the return operator requires a copy constructor in the class. Although the copy is nailed when the function exits, I'd like to eliminate the copy itself.

Perhaps the compiler is smart enough to optimize and inline everything by itself, excluding unnecessary copying. But we have to check it. It would be nice if someone would conduct tests and measurements. Because I often find myself faced with such a dilemma too.

 
Alexey Navoykov:

As someone has already pointed out, the correct way to do this is to return a smart pointer from a function. All this is implemented in MQL. But it's not as convenient to use as in C++, because the pointer switch must be implemented via method, not via switch operator. By the way, for the task at hand I suppose shared_ptr is not necessary, unique_ptr will be enough.

Alternatively, the created pointer inside the function could be immediately placed in some global array, which would be trashed at the end of the program. At the same time, the user can free the object's memory at any moment by calling a special function (not delete). It's like CloseHandle in WinApi.

Perhaps the compiler is smart enough to optimize everything and inline it all by itself, eliminating unnecessary copying. But we have to check it. It would be nice if someone would carry out tests and measurements. Otherwise I often find myself faced with such a dilemma too.

I'm publishing my implementation below - anyway these smart-pointers are created temporarily, and as a result I've created and nailed down more objects than I had ;-).

Of course, I have in mind a variant of global array, but it's so ugly! Especially because I wanted to clean up by timer (because the program may run for days), and the timer in MQL can't be attached to a class/object - it only comes from the global handler.

The compiler does not help here - tested - the local object by return is duplicated and then nailed. There is no optimal move in this case.

template<typename T>
class auto_ptr
{
  private:

    class Reference
    {
      public:
        int count;
        Reference(): count(0) {}
    };

    T *data;
    Reference *reference;

    void remove()
    {
      if(reference != NULL)
      {
        reference.count--;
        if(reference.count == 0)
        {
          delete data;
          delete reference;
        }
      }
    }

    
  public:
    auto_ptr(): data(NULL), reference(NULL)
    {
    }
    auto_ptr(T *ptr): data(ptr), reference(ptr == NULL ? NULL : new Reference())
    {
      if(reference != NULL) reference.count++;
    }
    auto_ptr(auto_ptr<T> &ref): data(ref.data), reference(ref.reference)
    {
      reference.count++;
    }
    
    ~auto_ptr()
    {
      remove();
    }
    
    void operator=(auto_ptr<T> &next)
    {
      if(&this != &next)
      {
        remove();
        
        data = next.data;
        reference = next.reference;
        reference.count++;
      }
    }
};
Reason: