Errores, fallos, preguntas - página 1874

 
Koldun Zloy:

Si estás seguro de que el constructor debe ser privado, no hay otra manera.

Un puntero inteligente es un objeto que contiene un puntero simple y asegura que se elimina a tiempo.

Esta es la opción más sencilla.

Hay punteros inteligentes más complejos.

Está muy bien escrito sobre ellos en este libro: https://rsdn.org/res/book/cpp/cpp_real_programmers.xml

Gracias. He probado diferentes variantes, pero no funciona
template <typename T>
struct PTR
{
  T* Ptr;
  
  PTR( void )
  {
  }
  
  void operator =( T* &Value )
  {
    this.Ptr = Value;
  }
  
  ~PTR( void )
  {
    Print(__FUNCSIG__);
    delete this.Ptr;
  }
};

class CLASS
{
private:
  static CLASS* Tmp;
  static PTR<CLASS> Ptr;
  
  CLASS()
  {
    CLASS::Ptr = CLASS::Tmp;
  }
};

static CLASS* CLASS::Tmp = new CLASS;
static PTR<CLASS> CLASS::Ptr;

void OnStart()
{
}

De hecho, es lógico que no funcione. No se puede hacer que el destructor de un puntero inteligente sea llamado antes que el destructor de la clase.

 

En lugar de especificar el error y dónde se produce, el compilador da un error interno no especificado #112

class CLASS {};

template <typename T>
class CLASS2
{
public:
  static void Func() {}
};

void OnStart()
{
  CLASS2<CLASS>::Func;  
}
 
fxsaber:
Gracias. He probado diferentes variantes, pero no funcionan.

En realidad, es lógico que no funcione. No se puede hacer que el destructor de un puntero inteligente sea llamado antes que el destructor de la clase.


Prueba de la siguiente manera:

template < typename T >
struct PTR
{
  T* Ptr;
  
  PTR( T* Value ) : Ptr( Value )
  {
  }
  
  ~PTR()
  {
    Print(__FUNCSIG__);
    delete Ptr;
  }
};

class CLASS
{
private:
  static PTR< CLASS > Ptr;
  
public:
  CLASS()
  {
      Print(__FUNCSIG__);
  }
  ~CLASS()
  {
      Print(__FUNCSIG__);
  }
};

static PTR< CLASS > CLASS::Ptr( new CLASS );

void OnStart()
{
}

No sé lo que estás haciendo, pero en MQL hacer el constructor privado sólo tiene sentido para el singleton.

 
Koldun Zloy:

Inténtalo de esta manera:

Gracias por el ejemplo detallado. Por desgracia, no tiene un constructor cerrado. No funciona así con uno cerrado, por supuesto.

Lo que necesito es que exista un objeto que esté oculto para todos. Al mismo tiempo, ningún otro objeto de este tipo podría ser creado de ninguna manera.

 
¿Es correcto en tal caso
class CLASS
{
public:
  ~CLASS()
  {
    static bool FirstRun = true;
    
    if (FirstRun && CheckPointer(&this) == POINTER_DYNAMIC)
    {
      FirstRun = false;
      
      delete &this;
    }
    
    Print(__FUNCSIG__);
  }
};

void OnStart()
{
  CLASS* Class = new CLASS;
  delete Class;
}

¿para que salga esto en el registro de ejecución?
void CLASS::~CLASS()
void CLASS::~CLASS()
delete invalid pointer


¿Y es correcto que el __FUNCSIG__ del constructor/destructor da un tipo void?

 
Koldun Zloy:

Inténtalo de esta manera:

¿Por qué el destructor del puntero inteligente es llamado antes que el destructor de la clase en tu versión, pero al contrario en la mía (aunque el constructor sea público)?
 
fxsaber:

Necesito tener un objeto que esté oculto para todos. Al mismo tiempo, no se podía crear otro objeto de este tipo de ninguna manera.


Eso es lo que se llama:"Singleton".

¿Por qué dices que no te conviene?

Este es un ejemplo de un singleton.

template < typename T >
struct PTR
{
   T* Ptr;
   
   PTR() : Ptr( NULL ){}
   PTR( T* ptr ) : Ptr( ptr )
   {
   }
   
   ~PTR()
   {
      Print(__FUNCSIG__);
      if( Ptr )delete Ptr;
   }
   
   void Set( T* ptr )
   {
      Ptr = ptr;
   }
};

class CLASS
{
   static PTR< CLASS > sPtr;
   
   CLASS()
   {
      Print(__FUNCSIG__);
   }
   
public:
   ~CLASS()
   {
      Print(__FUNCSIG__);
   }
   
   static CLASS* GetPtr()
   {
      if( !sPtr.Ptr ){
         sPtr.Set( new CLASS );
      }
      return sPtr.Ptr;
   }
};

static PTR< CLASS > CLASS::sPtr;

void OnStart()
{
   CLASS* ptr = CLASS::GetPtr();
}
 
fxsaber:
¿Es correcto en tal caso
¿para que salga esto en el registro de ejecución?


¿Y es correcto que el __FUNCSIG__ del constructor/destructor da un tipo void?


Nunca lo hagas

delete &this;
 
fxsaber:
¿Es correcto enviar esto al registro de ejecución en este caso?

¿Y es correcto que el __FUNCSIG__ del constructor/destructor salga de tipo void?


Sí, lo es.
 
Koldun Zloy:


Eso es lo que se llama:"Singleton".

¿Por qué dices que no te conviene?

Este es un ejemplo de un singleton.

Muchas gracias, ¡funciona!

template < typename T >
struct PTR
{
   T* Ptr;
   
   PTR( void ) : Ptr(NULL)   
   {
   }
   
   PTR( T* ptr ) : Ptr(ptr)
   {
   }
   
   ~PTR( void )
   {
     if (this.Ptr)
       delete this.Ptr;
   }
   
   bool Set( T* ptr )
   {
      this.Ptr = ptr;
      
      return(true);
   }
   
   void operator =( bool )
   {
   }
};

class CLASS
{
private:   
   static PTR<CLASS> sPtr;
   
   CLASS()
   {
   }
   
public:
  static bool Set()
  {
    return(CLASS::sPtr.Ptr ? false : CLASS::sPtr.Set(new CLASS));
  }
};

static PTR<CLASS> CLASS::sPtr = CLASS::Set();

void OnStart()
{
}

Pero sigue siendo un misterio.

Foro sobre trading, sistemas de trading automatizados y comprobación de estrategias

Bichos, errores, preguntas

fxsaber, 2017.04.25 10:34

¿Por qué se llama al destructor del puntero inteligente antes que al destructor de la clase en tu versión y al contrario en la mía (aunque el constructor sea público)?