czwartek, 19 sierpnia 2010

Przekazywania wartości do funkcji ciąg dalszy oraz klasa finalna w C++

Cóż - ostatnia zagadka była nieco trudna - przyznaję. Po raz kolejny mogę pogratulować poprawnego rozwiązania beluosusowi. Postaram się pokrótce wyjaśnić, o co w niej chodziło.

Mieliśmy zdefiniowaną funkcję void f(), która przyjmowała nieokreśloną liczbę argumentów. Tak naprawdę znaliśmy tylko pierwszy argument, który to oznaczał, ile dodatkowych argumentów owa funkcja będzie przyjmować. Następnie wczytywaliśmy dodatkowe argumenty za pomocą funkcji z nagłówka cstdarg.
W językach C oraz C++ przekazujemy argumenty w następujący sposób:
f(a,b,c)
Gdzie a,b,c są oczywiście argumentami. Nie każdy się jednak zastanawiał, jak to działa od środka.
Załóżmy, że mamy następujący program:

int f(int a, int b) {
        return 123;
}

int main() {
        int a=2, b=3;
        f(a,b);
        return 0;
}

Jeżeli każemy naszemu kompilatorowi wygenerować kod asemblerowy naszego programu (w przypadku GCC musimy użyć atrybutu -S), to po dużym uproszczeniu będziemy mogli zobaczyć coś takiego.

movl    $2, -12(%ebp)
        movl    $3, -8(%ebp)
        pushl   -8(%ebp)
        pushl   -12(%ebp)
        call    f

Oznacza to mniej więcej, że kopiujemy wartość 2 do rejestru o adresie -12(%ebp) (nasza zmienna a), oraz wartość 3 do rejestru o adresie -8(%ebp). Następnie wrzucamy oba te rejestry na stos (czyt. - dodajemy je do listy argumentów) po czym wywołujemy instrukcję call f, która wywołuję funkcję int f() w oparciu o argumenty pobrane ze stosu. Należy pamiętać, że argumenty wrzucamy na stos w odwrotnej kolejności.
Ot cała filozofia.

Wymyślanie zagadek nie należy do najłatwiejszych zajęć, tak więc skorzystam z zasłyszanego kiedyś gotowca. Zagadka dająca odpocząć troszeczkę od programowania niskopoziomowego.
W języku Java istnieje słowo kluczowe final, które w zależnie od kontekstu ma różne znaczenia. W tej zagadce zajmiemy się użyciem tego słowa w stosunku do klas. W Javie klasą finalną nazywamy klasę, z której nie możemy dziedziczyć.
I na tym będzie polegać Wasze zadanie. Zaprojektujcie klasę Klasa, dla której nie będzie możliwe utworzenie obiektu klasy pochodnej.

class Klasa {
 // TUTAJ MODYFIKACJA
  public:
    void f() { // publiczna funkcja skladowa, user musi miec mozliwosc wykonania jej w swoim programie
       cout << "Czesc, jestem klasa finalna!\n";
    }
};

class Dziecko : public Klasa {
};

int main() {
 Dziecko obj; // NIEDOZWOLONE!
 return 0;
}
Miłej zabawy.

2 komentarze:

  1. Zapewne liczysz na statyczną funkcję zwracającą wskaźnik do stworzonego obiektu ale żeby zrobić na przekór dam inne rozwiązanie. Spełnia wymogi zadania ale nie jest to klasa finalna. ;)

    http://pastebin.pl/27075

    OdpowiedzUsuń
  2. naraszcie znalazam stronkę która mnie interesuje :D


    mrocznybibliotekarz.blogspot.com ---- zapraszam do książek



    OdpowiedzUsuń