Frage

Ich habe einige Struktur:

struct A
{
 const char* name_;
 A* left_;
 A* right_;
 A(const char* name):name_(name),
      left_(nullptr),
      right_(nullptr){}
 A(const A&);
 //A(const A*);//ToDo
 A& operator=(const A&);
 ~A()
 {
  /*ToDo*/
 };
};
/*Just to compile*/
A& A::operator=(const A& pattern)
{

 //check for self-assignment
 if (this != &pattern) 
 {
  void* p = new char[sizeof(A)];
 }
 return *this;
}

A::A(const A& pat)
{
 void* p = new char[sizeof(A)];
 A* tmp = new (p) A("tmp");
 tmp->~A();
 delete tmp;//I WONDER IF HERE I SHOULD USE DIFFERENT delete[]?
}

int _tmain(int argc, _TCHAR* argv[])
{
 A a("a");
 A b = a;
 cin.get();
 return 0;
}

Ich weiß, das ist bei weitem nicht ideal und noch lange nicht fertig. Aber ich würde gerne wissen, ob ich mein Gedächtnis in der richtigen Art und Weise bin zu löschen (bitte erzähl mir nicht, wie man es richtig tun. Ich versuche es aus mir Abbildung).

Dies ist andere Frage href="https://stackoverflow.com/questions/2585508/generalization-arrows"> was mir wirklich wichtig ist.

War es hilfreich?

Lösung

void* p = new char[sizeof(A)];
A* tmp = new (p) A("tmp");
tmp->~A();
delete tmp;//I WONDER IF HERE I SHOULD USE DIFFERENT delete[]?

Nein. Sie haben bereits die Destruktor aufgerufen, so ist es nicht korrekt löschen zu nennen, die einen anderen Destruktoraufrufs verursacht. Sie müssen nur den Speicher freizugeben. z.

delete[] static_cast<char*>(p);

Wenn Sie für die Verwendung mit der Platzierung new rohen Speicher Zuweisung ist es konventionelleren direkt eine Zuordnungsfunktion zu verwenden. z.

void* p = ::operator new[](sizeof(A));
A* tmp = new (p) A("tmp");
tmp->~A();
::operator delete[](p);

Betrachten wir etwas zu tun, einfacher, though. Dieser Block könnte mit einem einzigen lokalen Variablen ersetzt werden, die robuster sein würde.

A tmp("tmp");

Andere Tipps

Wenn Sie den Speicher mit p = new[…] zuweisen, dann sollten Sie ausplanen mit delete[] p [1] , keine Ausnahmen.

Do not mess with tmp, nachdem er tot ist.

(Placement neue zuteilen Speicher nicht, wird der Destruktor nicht die new char[sizeof(A)] modifizieren, so dass sie auf die Frage nicht ein.)

[1]: Sie sollten p als char* erklären. Oder werfen p zu einem char* in delete[].

Wenn Sie Speicher für einen Zeiger in der Klasse sind, die Zuteilung sollte die destructor ausplanen (löschen), um den Speicher auch:

class Node
{
  char * name_;
  Node * p_left;
  Node * p_right;

  Node(const char * new_name)
  : name_(NULL), p_left(NULL), p_right(NULL)
  {
    size_t size = strlen(new_name);
    name_ = new char [size + 1]; // + 1 for terminating null
  }
  ~Node()
  {
     delete[] name_;
  }
};

ich sehr empfehlen:

  1. Verwenden std::string statt char * für Text.
  2. Verschieben Sie die Links in einer Basisklasse (Präferenz ist Vorlage für der Datenabschnitt des Knotens.}

Die Basisklasse ermöglicht es Ihnen, die Knoten zu verschiedenen Datentypen anpassen:

struct Node
{
    Node * p_left;
    Node * p_right;
};

struct Name_Node
: public Node
{
  std::string name;
};

struct Integer_Node
: public Node
{
  int value;
};

OTOH, die Sie verwenden std::map oder std::list nach dieser Übung möchten.

Um Speicher zum Beispiel von A nur Schreib A* p = new A("tmp"); zuordnen. Es wird Speicher und invoke Konstruktor zuweisen. Dann nutzen Sie delete p; aufzurufen destructor und ausplanen Speicher. Ich kann keine Notwendigkeit sehen, für die Verwendung Platzierung Form von neuen in Ihrem Fall.

A::A(const A& pat)
{
 void* p = new char[sizeof(A)];
 A* tmp = new (p) A("tmp");
 tmp->~A();
 delete tmp;//I WONDER IF HERE I SHOULD USE DIFFERENT delete[]?
}

Ja, Sie sollten löschen [verwenden], da Sie den Speicher mit neu angelegten []. Darüber hinaus, bevor Sie den Konstruktor (in diesem Fall eine Kopie Konstruktor) der Speicher erreichen bereits zugeteilt worden ist, so gibt es keine Notwendigkeit, es wieder zu verteilen, das ist, was es scheint, dass Sie hier zu tun versuchen.

Wenn Sie ein Objekt löschen, die destructor (~ A in diesem Fall) wird automatisch aufgerufen, so gibt es keine Notwendigkeit, sie explizit aufrufen, wenn Sie eine Platzierung neuer verwenden. So gibt es keine Notwendigkeit, in dem Lösch explizit die Speicher für das Objekt zugewiesen entfernen sich, nur für die Mitglieder, dass es besitzt.

Der Copy-Konstruktor sollte einfach die wichtigen Informationen kopieren aus dem Dinge kopiert werden. Schließlich setzt sich der Code hier eine Zeichenfolge: A a("a");, so dass Sie einen String-Konstruktor benötigen werden in der Lage sein, diesen Anruf zu machen:

A::A(const std::string& name)
{
   //Do stuff
}
scroll top