DevCrowd to chyba jedyna sensowna konferencja w Szczecinie. 22. kwietnia (sobota) odbędzie się tradycyjnie w budynku Wydziału Informatyki ZUT w Szczecinie.
Darmowa rejestracja jest tutaj.
The next gen of old-school blogging
DevCrowd to chyba jedyna sensowna konferencja w Szczecinie. 22. kwietnia (sobota) odbędzie się tradycyjnie w budynku Wydziału Informatyki ZUT w Szczecinie.
Darmowa rejestracja jest tutaj.
Biblioteka standardowa C++ w wielu miejscach oczekuje od typów, z którymi pracuje implementacji operatora< (alternatywą jest podanie własnego komparatora). Jest tak chociażby w std::sort, std::map lub std::binary_serch. Weźmy za przykład następującą klasę:
struct person { string first_name; string last_name; string city; int year_born; bool is_male; }; |
Aby posortować std::vector<person>, powinniśmy zaimplementować operator<, który spełnia strict weak ordering:
sleep(300); |
Ile śpimy? 0.3s (300ms)? 5 minut (300s)? A może parametrem powyższego sleep jest jeszcze inna jednostka? Bez zajrzenia do dokumentacji – albo kodu – nie ma na to pytanie odpowiedzi. Akurat w przypadku jednostek czasu C++11 wprowadził zestaw klas odpowiedzialnych za nie, więc można napisać taki zupełnie jednoznaczny kod:
this_thread::sleep_for(chrono::seconds(30)); this_thread::sleep_for(500ms); // C++14 |
Yay. Przykładowo, wpisy z tagiem D są dostępne pod adresem http://www.krzaq.cc:8080/pl/tag/d
Następnym krokiem jest edycja postów.
Commit był całkiem spory, ale nie bardzo mam na co zwrócić szczególną uwagę. Może na najdłuższą kwerendę w HQL jaką na razie napisałem:
Dość często spotykam się z kodem wyglądającym w przybliżeniu tak:
int x = rand()%200-100; int y = rand()%200-100; |
Czy zauważyliście już błąd? Jeśli tak lub nie, to możliwe, że nie macie racji – nie da się z powyższego kodu wywnioskować jaka była intencja programisty – czy to miał być kod losujący wartość z przedziału [-100, 99] czy też [-100, 100].
Pomijając nieczytelność/niejawność zamiarów, rand ma jeszcze następujące problemy:
Ciężko nie wspomnieć o słynnym wykładzie “rand() Considered Harmful”: [yt][ch9]
Przez ostatnie kilka dni byłem na drugim końcu Polski (dosłownie, trasa Przemyśl-Szczecin to dramat), i nie bardzo miałem możliwości pracy nad rozwojem Pieruna (lub nawet codziennym postowaniem). Teraz wróciłem; najbliższe cele to:
Gdy zakończę powyższe będę mógł poważnie myśleć o przesiadce produkcyjnej na Pieruna (to by ewentualnie wymagało dodania jeszcze jakiegoś redirecta starych linków na nowe).
Ten wpis jest skierowany do nowicjuszy i jest odpowiedzią na nagminną praktykę uczenia C++ jako C with classes (witamy w roku 1984), skutkującą potem zalewem kodu fatalnej jakości na wszelkiej maści forach.
tl;dr: prawie nigdy
Weźmy za przykład następujące klasy:
struct base { virtual void foo(int value = 42) { cout << __PRETTY_FUNCTION__ << ": " << value << endl; } }; struct derived : base { virtual void foo(int value = 100) override { cout << __PRETTY_FUNCTION__ << ": " << value << endl; } }; |
Nic niezwykłego, typowy dynamiczny polimorfizm. Każdy znający podstawy C++ powinien zdawać sobie sprawę, że w poniższym kodzie dwukrotnie zostanie wywołana funkcja derived::foo:
derived obj; base* b = &obj; derived* d = &obj; b->foo(); d->foo(); |
Zaskakujące może jednak być faktyczne wyjście:
virtual void derived::foo(int): 42 virtual void derived::foo(int): 100 |
Dlaczego wywołania, które powinny być identyczne jednak takie nie są?
Jeśli chodzi o C++ to mam o sobie całkiem wysokie mniemanie. Niemniej jednak, nie ma nikogo kto by znał ten język w całości. Ostatnio na forum, w dziale Newbie, zobaczyłem pytanie zawierające kod zbliżony do następującego:
// foo.hpp struct foo { void bar(int baz); }; // foo.cpp void foo::bar(int baz = 42) { // ... } |
Moją pierwszą odpowiedzią było “to się nie ma prawa skompilować”.
Dość często mi się to myli, jest to więc kolejna doskonała okazja do sprawdzenia, czy zapisanie informacji wspomaga jej retencję.
W kilku słowach: parametr to zmienna/stała będąca częścią prototypu funkcji, a argument to konkretna wartość do niej przekazana.
void foo(int a); int main() { foo(42); } |
W powyższym przykładzie a jest parametrem, a 42 argumentem.