poniedziałek, 9 sierpnia 2010

Zagadka - zmiana wartości składnika stałego obiektu bez użycia modyfikatora.

Poprzednia zagadka została rozwiązana przez beluosusa, któremu chciałbym z tego miejsca pogratulować.

Przykładowa metoda zmieniająca wartość tegoż składnika:
void TClass::change(int i) const {
        TClass *wsk = const_cast<TClass*>(this);
        wsk->a = i;
}

Ten sam człowiek jest pomysłodawcą zmodyfikowanej (czytaj: trudniejszej) wersji zagadki. Oto jej treść:

Mamy klasę TClass, posiadającą prywatny składnik 'int a', oraz metodę get(), zwracającą wartość tegoż składnika. Utwórz stały obiekt tej klasy, a następnie zmień wartość składnika a BEZ UŻYCIA MODYFIKATORA. Całość powinna pasować do następującego wzorca:

class TClass {
    int a;
public:
    TClass(int i = 0) {
        a = i;
    }
    int get() const {
        return a;
    }
};

int main() {
    const TClass obj;
    cout << obj.get() << "\n"; // niech wypisze 0.
        // W TYM MIEJSCU WPROWADŹ SWOJĄ MODYFIKACJĘ.
    cout << obj.get() << "\n"; // niech wypisze 5.
    return 0;
}

Miłej zabawy. ;-)

8 komentarzy:

  1. Wątpię czy trudniejszej aczkolwiek życzę komuś powodzenia. Sam zaś nie będę odpowiadał na swoje pytanie. ;)

    OdpowiedzUsuń
  2. #include
    using namespace std;

    class TClass {
    int a;
    public:
    TClass(int i = 0) {
    a = i;
    }
    int get() const {
    return a;
    }
    };

    int main() {
    const TClass obj;
    cout << obj.get() << "\n"; // niech wypisze 0.

    const TClass *Schrankenwarterhaus = &obj;
    TClass *eyjafjallajokull = (TClass*)Schrankenwarterhaus;
    *eyjafjallajokull=5;

    cout << obj.get() << "\n"; // niech wypisze 5.
    system("PAUSE");
    return 0;
    }

    OdpowiedzUsuń
  3. @Rekin: przekombinowane i rzutowanie w stylu C, nieładnie. :P Zdecydowanie wystarczy jedna linijka.

    OdpowiedzUsuń
  4. No już wiem że wystarczy ;-)
    A przekombinowane to są chyba tylko nazwy :D

    OdpowiedzUsuń
  5. Ta jedna linijka to:
    *((int *)&obj) = 5;

    Ale to już przykład maksymalnego oszustwa. :D

    OdpowiedzUsuń
  6. Warto zaznaczyć, że to będzie działać tylko dlatego ze nie ma vtable :>

    OdpowiedzUsuń
  7. @Railis: akurat sposobem, który podałeś będzie działać. Proszę jednak używać rzutowania w stylu C++ - oto chodzi w tym zadaniu. :) A im gorsze oszustwo tym lepiej, w końcu to nie ma być program użytkowy. ;)

    OdpowiedzUsuń
  8. Myślałem, o castowaniu w stylu c++, niemniej jednak ten sposób ma o wiele bardziej haksiorski i egzotyczny wygląd.

    OdpowiedzUsuń