Frage

  

Update 1:

     

Korrigierte Unsinn Code! Vielen Dank für die Kommentare, ich machte einen Hash-Wert des ersten Schnipsel, oops.

     

Update 2:

     

Auch aktualisierte Frage Titel, wie die Verwendung von dynamic_cast wurde darauf hingewiesen, wie nicht notwendig, nach Antworten.

Was ich versuche, hier zu erreichen, ist eine tiefe Kopie mit starken Typen; Ich möchte in der Lage sein Class2 von Class2 an eine andere Instanz zu kopieren; aber ich mag auch die CopyTo-Funktion aus dem Class1 verwenden, die die Basis ist. Diese Idee kommt aus meiner C # Erfahrung, wo in der Regel würde ich nur den Rückgabetyp (siehe C # Snippet) generic machen.

void Class1::CopyTo(Class1 *c1)
{
    // Write data in to c1 from this instance.
    c1->exampleData = exampleData;
}

// Class2 inherits Class1
Class2 *Class2::Copy()
{
    Class2 *c2a = new Class2();
    CopyTo(c2a);

    Class2 *c2b = dynamic_cast<Class2*>(c2a);
    return c2a;
}

Und hier ist die Art und Weise würde ich so es in C #:

public class Class1
{
    T Copy<T>()
        where T : Class1
    {
        /* Can't remember the best way to do this in C#;
         * basically if T was Class2 this would need to create
         * a new instance of that class, and the same goes for
         * Class1. */         
        T copy = createNewInstance();

        // Copy the data from this to 'copy'.
        copy.exampleData = exampleData;

        return copy;
    }
}

Nun, im Vergleich zu C # Schnipseln, die C ++ Code-Schnipsel stinkenden fühlen. Ist es möglich, ohne Zeiger, dies zu tun, oder ist auf diese Weise am besten Praxis?

War es hilfreich?

Lösung

Ich bin mir nicht sicher, was Sie versuchen zu erreichen, da der Code noch nicht viel Sinn macht. Allerdings glaube ich, sollte folgendes nähern, was Sie zu tun versuchen. Beachten Sie, dass I nicht Verwendung Heap-Speicher. Es ist nicht notwendig, und es würde auslaufen Speicher

template <typename T>
T Class1::Copy()
{
    T instance;
    CopyTo(&instance);
    return instance;
}

Das funktioniert, weil Sie einen (polymorphen) Zeiger auf instance zur CopyTo Methode von Class1 passieren.

Dann könnten Sie den Code wie folgt aufrufen:

Class2 x1;
// Fill x1
Class2 x2 = x1.Copy<Class2>();

Allerdings dieser Code noch riecht, weil es nicht idiomatischen C ++ ist: In C ++, würden Sie in der Regel eine Kopie Konstruktor schreiben statt. Spät gebundene Copy Methoden existieren, aber sie sind sehr selten benötigt, und die oben nicht zu spät gebunden ist (aber weder sind C # -Code).

Andere Tipps

Ich bin mir nicht klar, was Sie fordern, aber beachten Sie, dass, wenn Sie sagen:

 Class2 *c2 = dynamic_cast<Class2*>(c1);

das Ergebnis des gegossenen NULL sein könnte, und Sie müssen für diese überprüfen.

Sie sollten ein wenig mehr auf dem Code-Schnipsel arbeiten. GetSomethingCopy wird einen Zeiger vom Typ Klasse 2 zu schaffen, der CopyTo geben wird. CopyTo versucht, eine Memberfunktion des empfangenen Zeiger aufrufen, die initialisiert wurde nie. Segmentierungsfehler und das Programm stirbt

Auch wenn das nicht die Anwendung töten, versuchen Sie zu dynamic_cast von Klasse 2 * * CLASS2 die fast nichts zu tun ist. Wenn das, was Sie beabsichtigen, ist der zurückgegebene Wert von CopyTo Gießen, müssen Sie wissen, dass Sie nicht auf Leere verwenden dynamic_cast kann *. Sie müssen entweder ändern CopyTo Signatur Class1 zurückzukehren (so dass Sie es später werfen kann), oder verwenden static_cast auf dem void *.

Beachten Sie, dass entweder Kopieren Sie eine virtuelle Funktion in Class1 ist, die in der Tat in Klasse 2 ausgeführt ist und macht einen Klasse 2-Objekt erstellen, oder aber das zurückgegebene Element kein Class2, sondern ein Class1 sein.

Der Name der Methode CopyTo ist verwirrend, da es nicht kopiert das Argument, sondern aus dem Argumente.

Und nach all dies, ich weiß noch nicht, was Sie fragen. Wo wollen Sie Stapelspeicher benutzen? Sie können einen Stapel zugeordnet Element an eine Funktion, sondern auf einen Stapel reserviert Element einen Zeiger / Verweis Rückkehr ist wieder ein Segmentierungsfehler: das Objekt zerstört wird, wenn die Funktion beendet und der Empfänger wird mit einem baumelnden Zeiger / Verweis gelassen werden.

Nun, wenn Sie Ihre Frage auf mehr theoretischer Natur ist, ob Sie auf einem Stapel zugeordnet Element verwenden dynamic_cast können, können Sie (vorausgesetzt, dass Class2 von Class1 erbt):

void f()
{
   Class2 c2;
   Class1 &c1 = c2; // c1 is a Class1 reference to a Class2 object

   dynamic_cast<Class2&>(c1).class2method(); 
   // or:
   dynamic_cast<Class2*>(&c1)->class2method();
}

Wenn Sie den Code aktualisieren, um einen Kommentar in dieser Antwort hinterlassen, damit ich feststellen, und es kann heute Abend korrigieren.

macht den Code keinen Sinn wie gesagt ... sowieso ich „erraten“ Sie statischen Guss verwenden könnten, wenn man nicht einen void * als Rück verwendet hat?

Ok nun der Code macht Sinn.

Sie brauchen keine dynamische Umwandlung, seine bereits vom Typ Klasse 2.

In Ihrer CopyTo Funktion würden Sie einen Zeiger auf ein Objekt zurückkommen, die auf dem Stapel erstellt wurden -. Das ist ein Ding der Unmöglichkeit, da das Objekt des Zeiger bei zerstört werden, wenn die Funktion zurück

In Antwort auf Ihre Frage, können Sie dynamic_cast auf einem Zeiger oder eine Referenz verwenden. In Ihrem Fall könnte zuteilen ich das Objekt dynamisch new Verwendung zurückgegeben werden, anstatt auf dem Stapel, dann könnte man sicher einen Zeiger zurück. Allerdings neige ich zur Verwendung von dynamic_cast als potentiellem Codegeruch zu sehen, und ein Zeichen dafür, dass eine virtuelle Funktion soll verwendet werden wird.

Nein, dynamic_cast funktioniert nur mit Zeigern und Referenzen. Sie konnten nichts zurückgeben Sie auf dem Stapel zuweisen sicher sowieso, also bin ich nicht sicher, wie Sie Ihren Code in diesem Fall zu ändern beabsichtigten.

Ah, jetzt ist das Problem klar. Die Antwort ist technisch nein, nicht withh dynamic_cast <>, aber ich bin Fehler wirklich zu sehen, warum Sie es trotzdem wünschen würden. Es scheint, Sie wollen einfach nur

void Class1::CopyTo(Class1& c1)
{
    // Write data in to c1 from this instance.
    c1.SomeIntValue = SomeIntValue;
}

// Class2 inherits Class1
Class2* Class2::Copy()
{
    Class2 *c2 = new Class2();
    CopyTo(*c2);
    return c2;
}
//or more idiomatic
Class2 Class2::Copy()
{
    Class2 c2
    CopyTo(c2);
    return c2;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top