Wpis z mikrobloga

#programowanie (subuj #bbpsuje jeżeli chcesz dostawać inne moje dziwne techniczne wytwory).

Jakiś czas temu wstawiłem taki post na forum mojego roku w #studbaza . Może kogoś zainteresuje:

=====================
Ktoś na wykładzie spytał się czy jest jakiś magiczny sposób na zmianę wartości zmiennej, która w klasie jest w sekcji private. Jeżeli ktoś chcę elegancką metodę, to tak jak powiedział wykładowca nic takiego w C++ nie istnieje. Jest za to metoda nieelegancka. Jeżeli dostosujemy się do terminologii wykładowcy gdzie używanie wskaźnika jest jak trzymanie odbezpieczonego granatu, to ta metoda jest niczym granie w piłkę plażową przy pomocy miny morskiej zamiast piłki.

Tutaj kod wraz z wynikiem działania programu i zaraz wyjaśniam na czym polega myk http://ideone.com/Owccdl
Nasza prawilna klasa, ma zmienną prywatną "a" i publiczną "b". Pomiędzy nimi są konstruktor i deklaracja funkcji, która ma je wyświetlać. W praktyce niezależnie od tego jakie funkcje sobie wpiszemy pomiędzy tymi zmiennymi i w jakich będą sekcjach, to fizycznie w pamięci będą obok siebie. Liczy się tutaj ich kolejność wpisania (jeżeli zamienicie "a" i "b" miejscami w kodzie, to w pamięci również będą odwrócone). Gdzie w tym czasie są funkcje? Magia tej całej zabawy z obiektowością polega, na tym, iż niezależnie ile utworzycie sobie obiektów danej klasy w pamięci kopiowane będą jedynie te zmienne natomiast każda funkcja występuje w pamięci dokładnie raz, gdzieś poza ciałami tych obiektów (no nie jest to takie byle jakie gdzieś, ale nie ma tu sensu, aż tak się rozdrabniać) i gdy wywołujecie dana metodę klasy pod maska następuje przeskok do tego jednego egzemplarza funkcji wraz z informacją, który obiekt, go wywołał.

W funkcji doMagic pobieram adres, gdzie znajduje się dany obiekt. Daje mi to informacje o tym, gdzie fizycznie w pamięci zaczynają się dane. Dalej rzutuje ten wskaźnik tak, aby C++ myślał, że mamy tutaj tablicę z elementami typu INT. Dalej to już podmiana wartości jak w zwykłej tablicy.

Czy to zawsze wygląda tak pięknie? Nie zawsze. Sprawdziłem na szybko i gdy zaczynamy używać funkcji wirtualnych (jeżeli jeszcze o nich nic nie było, to będzie za 1-2 wykłady), to na początku przed naszymi wartościami pojawi się wskaźnik pokazujący, gdzie jest właściwa funkcja obiektu. Może jakbym się jeszcze pobawił, to bym znalazł jakieś inne wyjątki (cuda mogą się dziać np przy włączonej optymalizacji).

Traktujcie to jako ciekawostkę, a nie coś czego normalnie się używa. Jeżeli trzeba zmodyfikować zmienną private, to napiszcie/użyjcie przygotowanych do tego celu funkcji. Jeżeli ich nie ma, to znaczy, że po prostu macie tam nic nie grzebać
  • 7
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@bigben93:
Ciekawostka spoko, ale tak jak napisałeś to prawie nigdy nie wygląda tak pięknie. Nie dość, że vtable to psuje (tu wierzę na słowo; optymalizacji nie sprawdzałem), wystarczy by jedna ze zmiennych była typu double, a druga int i sam wskaźnik do inta już tak łatwo nie pozwoli nam modyfikować prywatnych składowych - inna reprezentacja typów i rozmiar. Jeśli składowa będzie czymś więcej niż POD (lub trafimy np. na idiom
  • Odpowiedz
@szatkus: To było pisane dla innych studentów jak na początku wspomniałem. W praktyce wiem, że pisanie programów ma w sobie sporo kałoplastyki ( ͡° ʖ̯ ͡°)
  • Odpowiedz