2016-04-28 13 views
0

Beim Lesen von Artikel 27 Gießen in Effektive C++ minimieren, versuchen Sie nicht zu static_cast*this in abgeleiteten Klasse zu Basisklasse zu verwenden. Es, weil static_cast<Base>(*this) ein temporäres Objekt der Basisklasse erstellen wird. Ich habe ein Beispiel wie folgt versucht, jedoch immer 10 mit verschiedenen Compilern wie clang 3.8 und gcc 4.9, 5.3.static_cast leitete dieses Objekt zur Basisklasse in C++

Bin ich falsch?

#include <iostream> 

    class A { 
    public: 
    int a; 
    virtual void foo() {std::cout << a << std::endl;} 
    }; 

    class B : public A { 
    public: 
    int b; 
    void foo() { static_cast<A>(*this).foo();} 
    }; 


    int main() { 
    B b; 
    b.a = 10; 
    b.foo(); 

    return 0; 
    } 

Die Frage ist, warum static_cast wird ein temporäres Objekt erstellen.

+2

Warum sollte es nicht 10 drucken? – emlai

+0

Was ist die Frage? Was ist das Problem, das du lösen willst? –

+0

Effektive C++ besagt, dass static_cast (* this) ein temporäres Objekt der Basisklasse erstellt. Unter dieser Annahme denke ich, dass es 0 ausgeben sollte. Ist das korrekt? – kwunlyou

Antwort

-1

Zunächst müssen Sie nicht Abgeleitete -> Base werfen, weil es automatisch passiert. Und ja, static_cast wird ein Objekt vom Typ erstellen, an den Sie gießen. In Ihrem Fall Polymorphismus können Sie entweder Verweis oder Zeiger verwenden können:

int main(){ 
    B b; 
    A &a = b; // no explicit cast needed 
    a.foo(); // will call B::foo 

    //OR 

    B *bPtr = new B; 
    A *aPtr = bPtr; // no explicit cast needed 
    aPtr->foo(); // same as above 
} 
+0

Danke. Eigentlich möchte ich ein Beispiel zur Überprüfung von static_cast erstellen (* Dies) wird ein temporäres Objekt erstellen. Aber ich habe mich selbst vermasselt. – kwunlyou

2

Ein sinnvolles Beispiel diese sein würde:

#include <iostream> 

class A { 
public: 
    virtual void foo() { std::cout << "A" << std::endl; } 
}; 

class B : public A { 
public: 
    virtual void foo() { std::cout << "B" << std::endl; } 
    void bar() { static_cast<A>(*this).foo(); } 
}; 

int main() { 
    B b; 
    b.bar(); 
} 

Ich würde erwarten barB zum Drucken, für foo ist eine überschriebene Methode. Es druckt stattdessen A.
Nun, das ist richtig aus der Sicht der Sprache, nicht so gut aus der Sicht des Entwicklers, der ein völlig anderes Ergebnis erwartet.

Es funktioniert, wenn Sie stattdessen die folgende Klasse verwenden:

class B : public A { 
public: 
    virtual void foo() { std::cout << "B" << std::endl; } 
    void bar() { static_cast<A*>(this)->foo(); } 
}; 

Auch arbeitet die folgenden als erwartet (aus Gründen der Klarheit hinzugefügt, dank @MORTAL in den Kommentaren):

class B : public A { 
public: 
    virtual void foo() { std::cout << "B" << std::endl; } 
    void bar() { static_cast<A&>(*this).foo(); } 
}; 

Wie auch immer, das Problem, mit dem Sie konfrontiert sind, heißt schneiden.
Deshalb ist die Verwendung von static_cast<A>(*this) nicht empfehlenswert, wenn Sie nicht wissen, was Sie tun.

Weitere Informationen finden Sie unter here.

+0

Danke. Eigentlich möchte ich ein Beispiel zur Überprüfung von static_cast erstellen (* Dies) wird ein temporäres Objekt erstellen. Aber ich habe mich selbst vermasselt. – kwunlyou

+1

Das Beispiel in der Antwort erstellt tatsächlich ein temporäres Objekt. – skypjack

+0

ich würde 'static_cast (* this) bevorzugen.foo() 'anstelle von' static_cast (this) -> foo() ' – MORTAL