Warsztat » Forum

[Programowanie] Wywołanie metody poprzez wskaźnik - dziwny błąd

Feb 10, 2008 | cmons |
39 wypowiedzi na 3 stronach:
1 2 3
flaczki
Jul 6, 2008

Odp: Wywołanie metody poprzez wskaźnik - dziwny błąd

Cytat:

Poziom twoich uwag = dno.


A czytanie co po niektórych wpisów na tym forum - bezcenne.  ;)
ConayR
Jul 8, 2008

Odp: Wywołanie metody poprzez wskaźnik - dziwny błąd

Cytat:

A co do wiedzy to już ją mam i nie zaimplementujesz (podpowiedź: zaimplementujesz tzn. będzie działać) override w C++. A GC (nie wszystkie typy, nie zawsze najwydajniej) tak. Masz coś do dodania z sensem? Bo jeśli chcesz się dalej przekomarzać to EOD z mojej strony.

Override w C# (bo o tym słowie kluczowym mowa) działa tak jak brak jakiegokolwiek znacznika przy kodzie w C++ - metoda będzie nadpisana i wywołanie Bazowa->wirtualna() na obiekcie który jest w rzeczywistości klasy Pochodna z override wirtualna() wywoła wirtualna() klasy pochodnej (wyjątkiem w C++ jest konstruktor i destruktor, bo pola Pochodna nie istnieją jeszcze/już; szczerze mówiąc nie wiem czy w C# dzieje się tak samo w tych dwóch wypadkach).

O override w C# pierwsza wspomniała Aithne w kontekście dyskusji o tym, że metoda raz zdefiniowana w C++ jako virtual jest zawsze virtual i virtual w pochodnych jest opcjonalnym słowem kluczowym. W związku z tym widząc class Pochodna : public Bazowa { virtual Foo(); }; bez znajomości Bazowa, nie wiesz czy Foo jest nadpisaną metodą z Bazowa czy nową metodą wirtualną. Czy ma ta wiedza praktyczne znaczenie czy nie, jest bez większego znaczenia, jeśli jednak chodzi o takie zastosowanie override, kod:
Kod: 

#define override
class Bazowa {
virtua Foo();
};
class Pochodna: public Bazowa {
virtual Bar();
override Foo();
};

rozwiązuje problem wiedzy z dziedziny "czy Foo() to nowa metoda wirtualna, czy nie". W tym kontekście dostajesz całkiem poprawną implementację override w ramach tego o czym była mowa. (bo metody wirtuanej w C++ nie możesz przesłonić)

Ale wracając do przekomarzania się - odnoszę wrażenie że już wiem dlaczego uważasz, że porównanie do GC jest chybione. Jeśli dlatego - spoko, masz absolutnie rację:

Cytat:

ConayR, przeczytałeś chociaż artykuł z linka? Nie będę ci cytował, ale ułatwię i powiem, że wystarczy przeczytać trzy zdania.

Tak, najwyraźnie jednak moje zdolności czytelnicze zasysają, bo nie czytałem tego:
http://msdn.microsoft.com/en-us/library/z8ew2153.aspx
Żyłem zatem w nieświadomości, że override można także używać w niezarządzanym kodzie. Bies mnie z tego błędu nie wyprowadził (świadomie lub nie), stąd i cała wymiana.

Jeśli jednak biesowi nie o to chodziło - trudno, muszę żyć z tym, że moje porównania mu się nie podobają.

Cytat:
Poza tym zastanów się po co ci zarządzany język do sprawdzenia przez kompilator czy w klasie bazowej jest metoda o tej samej nazwie.

Nie chodziło o kompilator a o osobę czytającą kod - odsyłam do pierwszej strony wątku.

Cytat:
Poziom twoich uwag = dno.

Dobrze, że takie komentarze to wyżyna savoir vivre. :) Ucz mnie!
siso
Jul 11, 2008

Odp: Wywołanie metody poprzez wskaźnik - dziwny błąd

Osz, qrka, nie wyrobię ;)

Cytat:
Override w C# (bo o tym słowie kluczowym mowa) działa tak jak brak jakiegokolwiek znacznika przy kodzie w C++

Herezja. Przeczytaj definicję: http://msdn.microsoft.com/en-us/library/ebca9ah3%28VS.71%29.aspx. "Brak jakiegokolwiek znacznika" w C++ działa dokładnie jak "brak jakiegokolwiek znacznika" i ani trochę inaczej. Override w C# nakłada natomiast pewien kontrakt na kod wywołujący, który to kontrakt musi zostać spełniony, ponieważ ani sygnatura ani widoczność overridowanej metody nie może się w klasie pochodnej zmienić. Nie możesz też overridować metody, która nie jest virtual. Czyli jednak coś robi. Abstrahuję teraz akurat od tego co robi z tym jakikolwiek kompilator, czy traktuje on to jako warning czy error, czy też może całkiem olewa - nie interesuje mnie to, ponieważ wystarczy, że w definicji zostały nałożone pewne ograniczenia. Takich ograniczeń nie jesteś w stanie nałożyć w C++ za pomocą prostego define. Kto mi zabroni przesłonić metodę niewirtualną, i napisać przy tym #define override?

Załóżmy, że chcę sobie zaimplementować algorytm QuicSort. Czy następujący kod mogę nazwać implementacją tegoż algorytmu?
Kod: 

template <class RandomAccessIterator>
void myFakeQS(RandomAccessIterator first, RandomAccessIterator last) {
    std::cout << "a kuku!" << std::endl;
}

Nie, jest to co najwyżej "stub" tej funkcji. Dobrze by było, gdyby on jednak sortował ten zakres, zamiast robić sobie jaja z użytkownika.

Podobnie Twoja "implementacja":
Kod: #define override

też powinna coś robić. NIe wystarczy, że sobie napiszesz, że coś jest przesłonięte. Tego typu ugododnienia mają wspomagać proces kompilacji. Jeśli w klasie bazowej zmienisz nagle sygnaturę, masz zostać poinformowany przez kompilator, że metody w klasach pochodnych już nie "overridują" metody bazowej. Przy Twoim prostym define nic się nie stanie, ponieważ jeśli sygnatura w bazowej się zmieni, to w pochodnej co najwyżej dojdzie do przeciążenia.

Dużo lepiej by było, żebyś po prostu przyznał, że trochę się zagalopowałeś, zamiast dalej brnąć w chaszcze ;)
Kot
Jul 10, 2008

Odp: Wywołanie metody poprzez wskaźnik - dziwny błąd

ConayR, naprawdę wystarczyło przeczytać trzy zdania z linka podanego w moim poście (http://msdn.microsoft.com/en-us/library/41w3sh1c.aspx)
1. override indicates that a member of a managed type must override a base class or a base interface member.
2. If there is no member to override, the compiler will generate an error.
3. override is also valid when compiling for native targets (without /clr).    BINGO!

Resztę skomentował siso.

Z mojej strony EOT. Szkoda, że na tym forum nikt nie docenia, że ktoś się chce podzielić wiedzą i czegoś nauczyć tylko szuka miejsca, gdzie udowodnić, że jest się lepszym. Tutaj skończyło się na ośmieszeniu, ale w ogóle po co taka czcza dyskusja, jak wystarczyło przeczytać trzy zdania.

Uważam, że poziom tej dyskusji = dno, dlatego, że jest w ogóle zbędna i udowadnia, że nie warto tu pokazywać czegoś, o czym inni nie wiedzą. Syf.
siso
Jul 12, 2008

Odp: Wywołanie metody poprzez wskaźnik - dziwny błąd

Z tym dnem to też nie jest tak. Każdy ma przecież prawo się wypowiedzieć, a jeśli się pomylił, to reszta może go poprawiać. Taka jest chyba jest idea forum, nie? ;) Nie ma co się obrażać ani gorączkować.

Niech Moc będzie z Wami!
Bez odbioru.

ConayR
Jul 12, 2008

Odp: Wywołanie metody poprzez wskaźnik - dziwny błąd

Cytat:

"Brak jakiegokolwiek znacznika" w C++ działa dokładnie jak "brak jakiegokolwiek znacznika" i ani trochę inaczej. Override w C# nakłada natomiast pewien kontrakt na kod wywołujący, który to kontrakt musi zostać spełniony, ponieważ ani sygnatura ani widoczność overridowanej metody nie może się w klasie pochodnej zmienić. Nie możesz też overridować metody, która nie jest virtual. Czyli jednak coś robi.

Mhm, zgadza się. Ale przecież nie pisałem o tym, czy #define override zmusza do czegoś kompilator (oczywiście, że nie jest kontraktem) tylko czy informuje o czymś czytającego kod. Pisząc o override w C++ pisałem dokładnie o takim zastosowaniu - od samego początku zaznaczałem, że o takie wykorzystanie override mi chodzi i tylko o takie. Zdawało mi się względnie jasne, że nie przypisuję #define magicznej właściwości zmuszania do czegoś kompilatora. Ja rozumiem, że pierwotnie to mogło nie być jasne, ale w poprzednim poście (chyba) czytelnie napisałem o co mi chodzi.

Cytat:
Abstrahuję teraz akurat od tego co robi z tym jakikolwiek kompilator, czy traktuje on to jako warning czy error, czy też może całkiem olewa - nie interesuje mnie to, ponieważ wystarczy, że w definicji zostały nałożone pewne ograniczenia. Takich ograniczeń nie jesteś w stanie nałożyć w C++ za pomocą prostego define. Kto mi zabroni przesłonić metodę niewirtualną, i napisać przy tym #define override?

Oczywiście nikt i z tym się nie kłóciłem. Zresztą bodajże na blogu Xiona nawet padł "fajny" pomysł na wstawianie override (lub dowolnego innego pustego define) gdzie tylko się da. Powtórzę się - nie twierdzę, że #define override wymusza cokolwiek na kompilatorze, to byłoby całkiem szalone twierdzenie. :) Ale nie o to przecież chodziło (choć jak widzę - niektórym dokładnie o to chodziło i stąd nieporozumienie).

Cytat:
[ciach]Podobnie Twoja "implementacja":
Kod: #define override

też powinna coś robić. NIe wystarczy, że sobie napiszesz, że coś jest przesłonięte. Tego typu ugododnienia mają wspomagać proces kompilacji.

Ależ na Teutatesa, cały czas zarzucasz mi coś, czego nie napisałem i zbijasz ten "argument". :) Już nie wspomnę nawet o tym, że to nie _moja_ "implementacja". ;) Tak, oczywiście, w ogólności masz rację, ja pisałem o szczególnym przypadku, który (miałem nadzieję) będzie wreszcie jasny. Nie jest jak widzę.

Cytat:
Jeśli w klasie bazowej zmienisz nagle sygnaturę, masz zostać poinformowany przez kompilator, że metody w klasach pochodnych już nie "overridują" metody bazowej. Przy Twoim prostym define nic się nie stanie, ponieważ jeśli sygnatura w bazowej się zmieni, to w pochodnej co najwyżej dojdzie do przeciążenia.

Ty naprawdę odniosłeś wrażenie, że ja tego nie rozumiem? Dzięki za wiarę. :)

Cytat:
Dużo lepiej by było, żebyś po prostu przyznał, że trochę się zagalopowałeś, zamiast dalej brnąć w chaszcze ;)

Hej, przyznałem dwie rzeczy: 1) żyłem w nieświadomości, że MSVC pozwala na użycie override w niezarządzanym C++; 2) #define override nie jest dla kompilatora kontraktem. Tyle że o ile 1) twierdziłem, że nie ma miejsca (owszem, mój błąd), o tyle nigdy nie twierdziłem, że 2) się stanie. Ja rozumiem, że fajnie jest zbić głupią tezę, ale ja tezy o #define override jako kontrakcie dla kompilatora nigdy nie postawiłem. Nie brnę w chaszcze tylko wołam z chodnika - hej, wcale mnie tam nie ma. :)
ConayR
Jul 12, 2008

Odp: Wywołanie metody poprzez wskaźnik - dziwny błąd

Cytat:

3. override is also valid when compiling for native targets (without /clr).    BINGO!

Zgadza się, czytając w pośpiechu przeczytałem invalid (dwukrotnie czytając ten wpis). Gdybym kliknął w link, pewnie nie żyłbym w nieświadomości. To się nazywa information bias - czytając 3. podpunkt zakładałem, że będzie tam "invalid" i tak też tekst przeczytałem. Nieuważnie. Zresztą przecież napisałem, że się w tej materii pomyliłem i jeśli o to chodziło biesowi, to faktycznie ma rację.

Cytat:
Szkoda, że na tym forum nikt nie docenia, że ktoś się chce podzielić wiedzą i czegoś nauczyć tylko szuka miejsca, gdzie udowodnić, że jest się lepszym.

Ależ ja doceniam, inaczej nie przeglądałbym tematów w poszukiwaniu ciekawych informacji. Rzecz w tym, że stosujesz klasyczną projekcję: nie udowadniam, że jestem lepszym (bo zakładam, że to miał być jakiś przytyk pod poim adresem), bo w wielu kwestiach lepszy nie jestem. Staram się jedynie wyjaśnić dlaczego uogólnianie tego, o czym pisałem, w przypadku kiedy miałem na myśli przypadek szczególny jest nie fair. Jeśli tego nie rozumiesz - trudno, będę żył. :)

Cytat:
Tutaj skończyło się na ośmieszeniu

Mhm, starasz się na siłę ośmieszyć mnie (vide nazywanie moich komentarzy dnem) jednocześnie całkowicie ignorując odpowiedź.

Cytat:
Uważam, że poziom tej dyskusji = dno, dlatego, że jest w ogóle zbędna i udowadnia, że nie warto tu pokazywać czegoś, o czym inni nie wiedzą. Syf.

Nie zazdroszczę podejścia. Smutne jest.
Strony:
1 2 3