Erros, bugs, perguntas - página 1874

 
Koldun Zloy:

Se tiver a certeza de que o construtor deve ser privado, não há outra forma.

Um ponteiro inteligente é um objecto que contém um simples ponteiro e assegura que é removido a tempo.

Esta é a opção mais simples.

Existem apontadores inteligentes mais complexos.

Está muito bem escrito sobre eles neste livro: https://rsdn.org/res/book/cpp/cpp_real_programmers.xml

Obrigado! Tentei variantes diferentes, mas não 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 facto, é lógico que não funciona. Não se pode fazer com que o destruidor de um ponteiro inteligente seja chamado antes do destruidor de classes.

 

Em vez de especificar o erro e onde ele ocorre, o compilador dá um erro interno não especificado #112

class CLASS {};

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

void OnStart()
{
  CLASS2<CLASS>::Func;  
}
 
fxsaber:
Obrigado! Tentei variantes diferentes, mas não funcionam.

Na verdade, é lógico que não funciona. Não se pode fazer com que o destruidor de um ponteiro inteligente seja chamado antes do destruidor de classes.


Tente da seguinte forma:

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()
{
}

Não sei o que está a fazer, mas em MQL tornar o construtor privado faz sentido apenas para o singleton.

 
Koldun Zloy:

Tente desta forma:

Obrigado pelo exemplo detalhado! Infelizmente, não tem um construtor fechado. Não funciona assim com um fechado, claro.

O que eu preciso é que exista um objecto que esteja escondido de todos. Ao mesmo tempo, nenhum outro objecto deste tipo poderia ser criado de forma alguma.

 
É correcto neste 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 enviar isto para o registo de execução?
void CLASS::~CLASS()
void CLASS::~CLASS()
delete invalid pointer


E é correcto que o __FUNCSIG__ do construtor/destrutor dá um tipo de vazio?

 
Koldun Zloy:

Tente desta forma:

Porque é que o destruidor de ponteiro inteligente é chamado antes do destruidor de classes na sua versão, mas o oposto na minha (apesar de o construtor ser público)?
 
fxsaber:

Preciso de ter um objecto que esteja escondido de todos. Ao mesmo tempo, outro objecto deste tipo não poderia ser criado de forma alguma.


É assim que é chamado:"Singleton".

Porque é que diz que não é adequado para si?

Aqui está um exemplo de um 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:
É correcto neste caso
para enviar isto para o registo de execução?


E é correcto que o __FUNCSIG__ do construtor/destrutor dá um tipo de vazio?


Nunca faça

delete &this;
 
fxsaber:
É correcto enviar isto para o registo de execução em tal caso?

E é correcto que o __FUNCSIG__ do construtor/destrutor produz tipo void-type?


Sim, é.
 
Koldun Zloy:


É assim que é chamado:"Singleton".

Porque diz que não lhe convém?

Aqui está um exemplo de um singleton.

Muito obrigado, 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()
{
}

Mas continua a ser um mistério.

Fórum sobre comércio, sistemas automatizados de comércio e testes estratégicos

Insectos, insectos, perguntas

fxsaber, 2017.04.25 10:34

Porque é que o destruidor de ponteiro inteligente é chamado antes do destruidor de classes na sua versão e o oposto na minha (mesmo que o construtor seja público)?