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:
  1. void TClass::change(int i) const {  
  2.         TClass *wsk = const_cast<TClass*>(this);  
  3.         wsk->a = i;  
  4. }  

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:

  1. class TClass {  
  2.     int a;  
  3. public:  
  4.     TClass(int i = 0) {  
  5.         a = i;  
  6.     }  
  7.     int get() const {  
  8.         return a;  
  9.     }  
  10. };  
  11.   
  12. int main() {  
  13.     const TClass obj;  
  14.     cout << obj.get() << "\n"// niech wypisze 0.  
  15.         // W TYM MIEJSCU WPROWADŹ SWOJĄ MODYFIKACJĘ.  
  16.     cout << obj.get() << "\n"// niech wypisze 5.  
  17.     return 0;  
  18. }  

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ń