2011-09-05 14 views
6

Czy to możliwe i dlaczego ktoś chciałby to zrobić?static_cast dla typów zdefiniowanych przez użytkownika

class Foo; 
class Bar; 

...... 

Foo foo; 
Bar bar = static_cast<Bar>(foo); 

Normalnie static_cast jest używany z typów liczbowych i wskaźników, ale może pracować z typów danych zdefiniowanych przez użytkownika, a.k.a klas?

+0

Tak, może działać, ale musisz również wiedzieć, jak go użyć - tutaj jest początek tego, co każda obsada robi w C++: http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-and-reinterpret-cast-be-used – birryree

Odpowiedz

10
Bar bar = static_cast<Bar>(foo); 

Ta obsada nie powiedzie się. Foo i Bar są niekompatybilne typów, o ile conajmniej jeden z następujących warunków:

  • Foo pochodzi z Bar, albo
  • Bar konstruktor które ma Foo, Or
  • Foo jest zdefiniowana przez użytkownika konwersja do Bar.

Najważniejsze pytanie nie dotyczy tego, czy uda się skutecznie, czy nie. Większe i aktualne pytanie powinno brzmieć: co chcesz wydostać z takiej obsady? Dlaczego chcesz zrobić coś takiego? Co ma robić? Mam na myśli, w jaki sposób zainicjować obiekt Bar z obiektu Foo?

Rozsądny sposób konwersji jednego typu do drugiego jest jeden z następujących sposobów:

Albo określić Foo jak:

class Foo : public Bar 
{ 
    //... 
}; 

lub zdefiniować Bar jak:

class Bar 
{ 
    public: 
     Bar(const Foo &foo); //define this constructor in Bar! 
}; 

Albo zapewnić funkcja konwersji w Foo jako:

class Foo 
{ 
    public: 
     operator Bar(); //provide a conversion function Foo to Bar! 
}; 
+1

A może się nie powiedzie? Co się stanie, jeśli 'Foo' zaimplementuje operatora konwersji na' Bar'? –

+0

@Kerrek: Zaktualizowałem swoją odpowiedź takimi danymi. – Nawaz

+1

To gwarantuje +1 –

11

Oto przepis:

Wyrażenie static_cast<T>(e) jest ważna tylko wtedy, gdy następujące zmienne definicja jest ważna

T x(e); 

gdzie x jakiś wymyślony zmienna.

Zasadniczo, dwa niepowiązane typy nie mogą być rzutowane na siebie nawzajem. Jednakże, jeśli jeden typ pochodzi od drugiego, lub gdy jeden definiuje funkcję konwersji do drugiego, lub konstruktor przyjmuje jeden argument drugiego typu - w tych przypadkach static_cast będzie dobrze zdefiniowany.

Czy to ma kiedykolwiek sens? Na przykład, jeśli T definiuje konstruktor, który przyjmuje pojedyncze U, a konstruktor to explicit, to static_cast<T>(e), gdzie e jest typu U, ma sens.

+1

Ma to szczególnie sens w kodzie ogólnym, na przykład, jeśli T może być typem zdefiniowanym przez użytkownika, ale może również być typem wbudowanym. Następnie, jeśli napisałeś '(T (e))' zamiast 'static_cast (e)' (extra parens, aby upewnić się, że nie jest to definicja 'e'), to jest to odpowiednik odlewu w stylu C do' ((T) e) ', a dla typów wbudowanych istnieje ryzyko, że zmieni się w' reinterpret_cast'. –

Powiązane problemy