Rzutowanie klas

0

jak mozna przy dziedziczeniu klasy w c++ zrobic taki myk ze: "A" dziedziczy po "B"

i zamiast tego
((B*)A)->xoxo();
to zrobic tak A->asB()->xoxo() ?

0
A->B::xoxo();
0
class B
{
public:
A* asA(){return (A*)this;}
}

class A: public B
{
void xoxo1();
void xoxo2();
}

Chce osiągnąc coś takiego, czy jest to możliwe? Bo ja twierdze że nie, ale jako że nie jestem zbyt inteligentny pytam się mądrzejszych.

0

Jeśli to 'to' sprowadza się do kwestii związanych z kompilacją, to da się to zrobić - daj deklarację zapowiadającą klasy A przed definicją B. Problem w tym, że taka konstrukcja jest mało bezpieczna i użyteczna, ponieważ klasa B nie jest klasą A, więc wywołanie metody asA będzie poprawne tylko dla klasy A i jej pochodnych, wszystkie inne wywołania będą błędne.

0

To jest jakiś hardkor co chcesz zrobić. To jest coś takiego:
Mamy klasę Zwierze i klasę Człowiek która z niej dziedziczy. Ty chcesz umozliwić obiektowi Zwierze udawać Człowieka (rzutowanie B na A). Zauważ ze Zwierze NIE MA takich umiejętności (metod) jak Człowiek. Próba odwołania się do nich spowoduje najpewniej wysypanie się programu, bo nie będzie dostępu do pól Człowieka z których metody będą chciały korzystać.
Samo wywołanie metod będzie działać, o ile nie będą to metody wirtualne, ale tak się po prostu nie robi ;]

@down miałem zaćmienie lekkie ;)

0
Shalom napisał(a)

Nie wiem czy zdajesz sobie sprawę z tego że każdy obiekt przechowuje w sobie informacje o swoich metodach.

A to od kiedy?

Próba odwołania się do nich spowoduje najpewniej wysypanie się programu, bo nie będzie dostępu do pól Człowieka z których metody będą chciały korzystać.

Niby dlaczego cokolwiek miałoby się wysypać? Pola są rozłożone w pamięci po kolei, więc jeżeli obiekt faktycznie został utworzony jako docelowy typ, to nie powinno być żadnego problemu.

0

ale najpierw trzeba wiedzieć, że to jest typ docelowy! W tym kodzie brakuje właśnie sprawdzenia czy konwersja jest możliwa.
Owszem takie sztuczki są robione w profesjonalnym kodzie, ale zawsze jest wbudowany lub udostępniony mechanizm weryfikacji typu (niekoniecznie oparty na RTTI).

0
class A;  // pewnie tego Ci zabraklo. kompilator w linii "X" musi znac nazwę "A" i *wiedziec* czym ona będzie!

class B
{
public:
A* asA(){return (A*)this;}   // linia X
};

class A: public B
{
void xoxo1();
void xoxo2();
};

btw1.
A* asA(){return (A*)this;}
powinno byc raczej parą i uzywac referencji, bo nigdy te wskazniki nie sa zerowe (obiekt B istnieje, prawda?):
A& asA() {return (A)this;}
A const & asA() const {return (A)this;}

btw2.
oczywiscie kod sie bedzie kompilowal, ale to nie znaczy ze takie podejscie jest ok.. jesli wprowadzisz wiecej klas dziedziczacych po Be, bedziesz mial sporo zabawy i upierdliwosci w pilnowaniu ze to-Be jest faktycznie tamtym-Aa a nie jakims-Ce

btw3.
jezeli kompilator Ci krzyczy errorami lub warningami ze nie da sie lub ze niebezpiecznie jest rzutowac z B na A, uzyj reinterpret_cast<A*>(this) lub dynamic_cast jezeli dodatkowo chcialbys miec runtimeowa kontrole poprawnosci typow (acz wtedy klasy te musza miec w sobie cokolwiek 'virtual')

0

W zasadzie dynamic_cast to jest chyba to o o chodzi... Mam rację?

1 użytkowników online, w tym zalogowanych: 0, gości: 1