Entries for tag "c++", ordered from most recent. Entry count: 152.
# int1, int2, int4, int8
Thu
31
May 2007
Ilekroć koledzy widzą mój kod, dziwią się, dlaczego swoje typedef-y nazwałem int1, int2, int4, int8, uint1 itd., zamiast int8, int16, int32, int64, uint8 itd. Ja wtedy pytam: Po co miałbym liczyć rozmiar w bitach, zamiast w bajtach? Wiem, że tak się najczęściej robi, ale to i tak są zawsze wielkrotności ósemki. Może w grach komputerowych za zebranie kryształka warto naliczyć graczowi całe 100 punktów zamiast jednego, bo to ma jakiś efekt psychologiczny, ale programiści powinni podchodzić do życia praktycznie. Dlatego dla mnie liczenie w bitach jest po prostu bez sensu. Operator sizeof też zwraca rozmiar w bajtach :P
Comments | #c++ #philosophy Share
# Policy-Based Design
Wed
30
May 2007
class DeletePolicy {
public:
template <typename T>
static void Destroy(T *p) { delete p; }
};
class ReleasePolicy {
public:
template <typename T>
static void Destroy(T *p) { if (p) p->Release(); }
};
class scoped_ptr<typename T, typename PolicyT = DeletePolicy>
{
public:
explicit scoped_ptr(T *p = NULL) : m_Ptr(p) { }
~scoped_ptr() { PolicyT::template Destroy<T>(m_Ptr); }
// ...
};
scoped_ptr<int, DeletePolicy> p1;
scoped_ptr<IDirect3DTexture9, ReleasePolicy> t1;
To przykład techniki zwanej Policy-Based Design, którą wynalazł Andrei Alexandrescu. Wszystkich zainteresowanych zabawami z językiem C++ zachęcam do zgłębiania tematu. Szablony to nie jest lekarstwo na wszystkie (jakże liczne) problemy rodzące się podczas programowania w tym języku, ale to jedna z potężnych i zaawansowanych technik. Znałem ją już wcześniej, ale teraz doceniłem i użyłem. Jak to się mówi w komentarzach na Allegro: Polecam! :)
Comments | #c++ #algorithms Share
# Pytanie o inteligentne wskaźniki
Mon
28
May 2007
Chcę sobie napisać tzw. inteligentne wskaźniki (po to żeby, przyznaję, uwolnić się od biblioteki Boost :) W związku z tym będę wdzięczny każdemu kto potrafi i znajdzie chwilę żeby odpowiedzieć na moje pytanie z tym związane w odpowiednim wątku forum.
Comments | #c++ #algorithms Share
# IntToStr, StrToInt
Fri
25
May 2007
Na dobry koniec dnia wyniki pomiaru wydajności moich nowych funkcji do konwersji między liczbą a łańcuchem - porównane z funkcjami systemowymi (plus konwersje do std::string, bo takich łańcuchów wszędzie używam i takich używają te moje funkcje). Wyniki w mikrosekundach na pojedyncze wywołanie, już podzielone przez liczbę wykonanych iteracji.
- DEBUG
- int > string
itoa : 0.244895 us
IntToStr (stary) : 3.20974 us
IntToStr (nowy) : 0.659205 us
- string > int
atoi : 0.270027 us
StrToInt : 0.391424 us
- RELEASE
- int > string
itoa : 0.137373 us
IntToStr (stary) : 0.225465 us
IntToStr (nowy) : 0.134297 us
- string > int
atoi : 0.0785857 us
StrToInt : 0.0589072 us
Comments | #c++ #algorithms Share
# Signed czy unsigned
Fri
25
May 2007
Czy do zapisywania rozmiaru danych, liczby bajtów, liczby elementów albo indeksu lepiej stosować liczbę całkowitą ze znakiem, czy bez znaku? Liczby ze znakiem są standardem w Delphi i mają wielu zwolenników dzięki swoim zaletom: Indeksy ujemne, jako niepoprawne, można stosować do oznaczenia wartości specjalnej (np. -1). Nie ma też obawy o "przekręcenie" przy zliczaniu w dół.
Ja jestem jednak zwolennikiem podejścia obowiązującego w C++, czyli stosowania typu bez znaku tam gdzie to możliwe (np. pod nazwą: unsigned, size_t, DWORD czy mój własny uint4). Zaleta tego podejścia to m.in. dwa razy większy dostępny zakres. Nie trzeba też sprawdzać poprawności liczby od dołu - wystarczy od góry. Jako wartości specjalnej można używać 0xFFFFFFFF (taką wartość ma na przykład stała std::string::npos zwracana przez std::string::find kiedy nic nie znaleziono).
Co wtedy z przechodzeniem tablicy w dół? Sposobem na to jest tzw. Pętla Tarlandila (tak sobie ją nazywam, bo nauczył mnie jej Tarlandil):
for (size_t i = RozmiarTablicy; i--; )
{
Tablica[i] = 0;
}
Jak chcesz to przeanalizuj dokładnie jak działa ta sprytna pętla, a jeśli nie, to uwierz na słowo że ona naprawdę przechodzi tablicę w dół od elementu ostatniego do pierwszego i nie straszne jej przekręcenie się liczby bez znaku poniżej zera :)
Comments | #c++ #philosophy #algorithms Share
# Rzucanie wyjątków w destruktorze
Fri
25
May 2007
W języku C++ jest zasada, że nie należy rzucać wyjątków w destruktorach. Destruktor to jedyny kod, który może zostać wykonany kiedy wyjątek leci - został już rzucony, a nie został jeszcze złapany. Dzieje się tak dla obiektów utworzonych na stosie. Nie może być na raz dwóch wyjątków. Kiedy jeden leci i drugi zostaje rzucony, program się wysypuje.
Jednak czy na pewno to jest dokładnie tak? Co jeśli od czasu do czasu chcielibyśmy zrobić w destruktorze coś więcej niż tylko zwolnić pamięć, na przykład otworzyć na chwilę jakiś plik za pomocą własnej klasy strumieni, która w przypadku błędu rzuca wyjątek?
Tu będzie dobra wiadomość: MOŻNA rzucać wyjątek w destruktorze i mimo że jeden już leci, ten drugi nie spowoduje wysypania programu o ile zostanie w porę złapany i nie wyleci poza destruktor! Nie daję głowy że tak jest zawsze (nie należę do tych "językoznawców", którzy z pasją studiują standard języka uważając go za cel sam w sobie), ale sprawdziłem to na trzech kompilatorach: Visual C++ 2005 Professional, GCC 4.1.2 oraz Intel ICC 9.1.
# INF-y i NAN-y
Sun
13
May 2007
Liczby zmiennoprzecinkowe typu float czy double mogą przyjmować pewne
specjalne wartości, m.in. oznaczające nieskończoność, nazywane -INF i
+INF, a osiągalne w C++ za pomocą nagłówka <limits> i wywołania
std::numeric_limits<float>::infinity().
Ciekawe jest, że w przeciwieństwie do liczb całkowitych dzielenie zmiennoprzecinkowe przez
zero nie powoduje "wywalenia" programu, ale daje w wyniku takie właśnie
nieskończoności.
Z mojego doświadczenia wynika, że zachowują się one absolutnie sensownie. -(+INF) daje -INF, -INF jest mniejsze od każdej liczby a +INF jest większe, -INF jest mniejsze od +INF, +INF - 2.f daje +INF, -INF * -2.f daje +INF itd. Zastanawia mnie więc, dlaczego wszyscy tych specjalnych wartości tak się boją, a nikt ich nie stosuje w swoim kodzie? Ostatnio znalazłem na to kolejny przykład - programiści nVidia w swoich przykładowych kodach używają liczby 1e32f jako wartości specjalnej.
# Visual C++ - debugger wchodzi do źródeł biblioteki standardowej
Fri
04
May 2007
Ano wchodzi... Jest to szczególnie niewygodne w przypadku używania STL. Wystarczy, że podając parametry do jakiejś funkcji czy metody robimy coś przy okazji, na przykład:
Funkcja(string("Łańcuch"), MojWektor[2]);
Zadałem o tym pytanie na forum i rozwiązanie się znalazło. Trzeba otóż:
std\:\:.*
Ponowne uruchomienie Visuala nie jest konieczne - wystarczy nowa sesja debugowania (F5).
Nowa wersja tego wpisu (po angielsku) znajduje się TUTAJ.