Fehler, Irrtümer, Fragen - Seite 1874

 
Koldun Zloy:

Wenn Sie sicher sind, dass der Konstruktor privat sein muss, gibt es keine andere Möglichkeit.

Ein intelligenter Zeiger ist ein Objekt, das einen einfachen Zeiger enthält und sicherstellt, dass dieser rechtzeitig entfernt wird.

Dies ist die einfachste Option.

Es gibt auch komplexere intelligente Zeiger.

In diesem Buch wird sehr gut über sie geschrieben: https://rsdn.org/res/book/cpp/cpp_real_programmers.xml

Ich danke Ihnen! Verschiedene Varianten ausprobiert, aber es funktioniert nicht
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()
{
}

Es ist eigentlich logisch, dass es nicht funktioniert. Sie können den Destruktor eines Smart Pointers nicht vor dem Destruktor der Klasse aufrufen.

 

Anstatt den Fehler und die Stelle, an der er auftritt, zu spezifizieren, gibt der Compiler einen nicht spezifizierten internen Fehler #112 aus

class CLASS {};

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

void OnStart()
{
  CLASS2<CLASS>::Func;  
}
 
fxsaber:
Ich danke Ihnen! Ich habe verschiedene Varianten ausprobiert, aber sie funktionieren nicht.

Eigentlich ist es logisch, dass es nicht funktioniert. Sie können den Destruktor eines Smart Pointers nicht vor dem Destruktor der Klasse aufrufen.


Versuchen Sie es auf folgende Weise:

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

Ich weiß nicht, was Sie tun, aber in MQL macht es nur für das Singleton Sinn, den Konstruktor privat zu machen.

 
Koldun Zloy:

Versuchen Sie es auf diese Weise:

Vielen Dank für das ausführliche Beispiel! Leider hat es keinen geschlossenen Konstruktor. Bei einem geschlossenen System funktioniert das natürlich nicht so.

Was ich brauche, ist ein Objekt, das vor allen anderen verborgen ist. Gleichzeitig konnte kein anderes Objekt dieser Art auf irgendeine Weise geschaffen werden.

 
Ist es in einem solchen Fall richtig
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;
}

um dies im Ausführungsprotokoll auszugeben?
void CLASS::~CLASS()
void CLASS::~CLASS()
delete invalid pointer


Und ist es richtig, dass der __FUNCSIG__ des Konstruktors/Destruktors einen void-Typ ergibt?

 
Koldun Zloy:

Versuchen Sie es auf diese Weise:

Warum wird der Smart-Pointer-Destruktor in Ihrer Version vor dem Klassen-Destruktor aufgerufen, in meiner aber umgekehrt (obwohl der Konstruktor öffentlich ist)?
 
fxsaber:

Ich brauche ein Objekt, das vor allen anderen verborgen ist. Gleichzeitig konnte ein weiteres Objekt dieser Art auf keine Weise erstellt werden.


So nennt man das:"Singleton".

Warum sagen Sie, dass es für Sie nicht geeignet ist?

Hier ist ein Beispiel für ein 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:
Ist es in einem solchen Fall richtig
um dies im Ausführungsprotokoll auszugeben?


Und ist es richtig, dass der __FUNCSIG__ des Konstruktors/Destruktors einen void-Typ ergibt?


Niemals tun

delete &this;
 
fxsaber:
Ist es richtig, dies in einem solchen Fall im Ausführungsprotokoll auszugeben?

Und ist es richtig, dass der __FUNCSIG__ des Konstruktors/Destruktors den void-Typ ausgibt?


Ja, das ist sie.
 
Koldun Zloy:


So nennt man das:"Singleton".

Warum sagen Sie, dass es nicht zu Ihnen passt?

Hier ist ein Beispiel für ein Singleton.

Herzlichen Dank, es funktioniert!

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

Aber es bleibt immer noch ein Rätsel.

Forum für Handel, automatisierte Handelssysteme und Strategietests

Wanzen, Wanzen, Fragen

fxsaber, 2017.04.25 10:34

Warum wird der Smart-Pointer-Destruktor in Ihrer Version vor dem Klassen-Destruktor aufgerufen und in meiner Version das Gegenteil (auch wenn der Konstruktor öffentlich ist)?