Ich habe gerade die folgenden Absätze in C++ 03 Standardentwurf relevant für den Zeiger auf die Elementkonvertierung gefunden. Zeiger auf Elementkonvertierung
4,11/2 Pointer an dem Mitglied Conversions
rvalue des Typs „Zeiger auf Mitglied von B vom Typ cv T“, wobei B einen Klasse-Typ ist, können zu einem R-Wert vom Typ umgewandelt werden "Zeiger auf Member von D vom Typ cv T", wobei D eine abgeleitete Klasse (Abschnitt 10) von B ist. Wenn B eine unzugängliche (Klausel 11), mehrdeutige (10.2) oder virtuelle (10.1) Basisklasse von D ist, a Programm, das diese Umwandlung erfordert, ist schlecht ausgebildet. Das Ergebnis der Konvertierung bezieht sich auf dasselbe Element wie der Zeiger auf das Element vor der Konvertierung, bezieht sich jedoch auf das Basisklassenelement, als wäre es ein Element der abgeleiteten Klasse . Das Ergebnis bezieht sich auf das Element in Ds Instanz von B. Da das Ergebnis den Typ "Zeiger auf Member von D vom Typ CV T" hat, kann es mit einem D-Objekt dereferenziert werden. Das Ergebnis ist das gleiche, als wenn der Zeiger auf Glied von B mit dem B-Unterobjekt von D. Der Nullelement Zeigerwert zu dem Nullelement Zeigerwert des Ziel type.52 dereferenziert wurde umgewandelt wird)
5.2.9/9 static_cast
rvalue des Typs „Zeiger auf Mitglied D vom Typ CV1 T“ können zu einem R-Wert des Typs „Zeiger auf Mitglied von B vom Typ CV2 T“ umgewandelt werden, wobei B ist eine Basisklasse (Klausel 10) von D, wenn eine gültige Standardkonvertierung von "Zeiger auf Element von B vom Typ T" nach "Zeiger auf Element von D vom Typ T" existiert (4.11) und cv2 dasselbe cv ist -Qualifikation als oder höher cv-qualification als, cv1.63) Der Nullelementzeigerwert (4.11) wird in den Nullelementzeigerwert des Zieltyps konvertiert. Wenn Klasse B das ursprüngliche Element enthält oder eine Basisklasse oder eine abgeleitete Klasse der Klasse ist, die das ursprüngliche Element enthält, verweist der resultierende Zeiger auf Element auf das ursprüngliche Element. Andernfalls ist das Ergebnis der Besetzung undefiniert. [Hinweis: Obwohl Klasse B nicht das ursprüngliche Element enthalten muss, muss der dynamische Typ des Objekts, auf dem der Zeiger auf Element dereferenziert wird, das ursprüngliche Element enthalten; siehe 5.5. ]
Also hier ist meine Frage. Wie 5.2.9/9 sagt, kann ein Zeiger auf Member von D in einen Zeiger auf Member von B umgewandelt werden, wenn eine gültige Konvertierung existiert, die in 4.11/2 beschrieben ist. Bedeutet dies, dass, wenn es ein Mitglied 'm' von D gibt, das nicht von B geerbt wurde, der Zeiger auf Element 'm' nicht auf den Typ des Zeigers auf Element von B geworfen werden kann?
class Base { };
class Derived : public Base
{
int a;
};
typedef int Base::* BaseMemPtr;
BaseMemPtr pa = static_cast<BaseMemPtr>(&Derived::a); // invalid, as per 5.2.9/9 ?
In der Notiz von 5.2.9/9, heißt es auch, dass, obwohl die Klasse B das ursprüngliche Element nicht enthalten muss, den dynamischen Typen des Objekts, auf das der Zeiger auf ein Element dereferenziert wird das ursprüngliche Element enthalten muss .
Ich bin verwirrt mit dem Wortlaut des Absatzes. Ist der obige Code gültig?
Ich suchte die Website, und es gibt eine ähnliche Frage, c++ inheritance and member function pointers, deren Antwort nur den Fall, dass die Konvertierung von Zeiger zu Mitglied der Basisklasse Zeiger auf Mitglied der abgeleiteten Klasse abgedeckt.
Sie weisen einem Zeiger auf Elementfunktionsvariable einen Zeiger auf Datenelementwert zu. Ansonsten, yep, "das Ergebnis der Besetzung ist undefiniert." – Potatoswatter
Danke, ich habe es behoben. – ashen