Ist es sicher, in eine Klasse zu konvertieren, die dasselbe Datenelementlayout, aber eine andere Implementierung aufweist?

8

Die erste Klasse wird für die private Vererbung verwendet, um das exakt gleiche Layout zu gewährleisten. Dies sollte Casting sicher machen.

%Vor%

In diesem trivialen Beispiel drucke ich zuerst das Datenelement int , gefolgt vom Element std::string data für Instanzen von data<true> .

%Vor%

Das data<false> druckt jedoch zuerst das Datenelement std::string , gefolgt vom Datenelement int .

%Vor%

Beispiel:

%Vor%

Demo: Ссылка

Wie die Demo zeigt, gibt es auch bei aktiviertem% ​​co_de% Flag keine Warnungen.

Nun, da sie das gleiche Layout haben, dachte ich, dass ich einfach zwischen den beiden Typen umwandeln könnte, um eine andere Art von statischem Polymorphismus zu erhalten; ohne die Kosten eines virtuellen Funktionsaufrufs.

Ist diese Verwendung sicher oder löst ich ein undefiniertes Verhalten aus?

    
user2296177 08.09.2016, 02:31
quelle

2 Antworten

1

Aus [expr.reininterpret.cast] / 11 in der Sprachspezifikation können Sie eine Referenz von einem Typ in einen anderen umwandeln (wenn Sie einen Zeiger auf einen anderen Typ setzen können).

Bei Ihren Klassenlayouts haben beide Typen eine gemeinsame Basisklasse, die alle Daten enthält. Die beiden abgeleiteten Typen fügen keine Datenelemente hinzu und fügen auch keine virtuellen Funktionen hinzu, sodass das Objektlayout für beide Klassen identisch ist.

So ist die Verwendung sicher, wenn Sie reinterpret_cast verwenden.

In diesem Fall ähnelt das dem Umwandeln in eine Referenz der Basisklasse und dem anschließenden Umsetzen dieser Referenz auf die andere abgeleitete Klasse.

    
1201ProgramAlarm 08.09.2016 04:13
quelle
1

Es ist mehr oder weniger, was hier beschrieben wird, der sogenannte Boost mutiertes Idiom .

Dort heißt es (Hervorhebung von mir):

  

Das Boost-Mutations-Idiom verwendet reinterpret_cast und hängt stark von der Annahme ab, dass die Speicherlayouts von zwei verschiedenen Strukturen mit identischen Datenelementen (Typen und Reihenfolge) austauschbar sind. Obwohl der C ++ - Standard diese Eigenschaft nicht garantiert, erfüllen praktisch alle Compiler dies . Darüber hinaus ist das mutierte Idiom Standard, wenn nur POD-Typen verwendet werden.

Hinweis : Diese Seite ist ziemlich veraltet, ich weiß nicht, ob die letzten Änderungen etwas an den oben genannten Garantien geändert haben.

    
skypjack 08.09.2016 08:59
quelle