Ogólne wskazówki dla programistów

Kadu

Spis treści

Kadu jest programem pisanym w języku C++

  • Pamiętaj o tym! Język C++ jest w dużym stopniu spadkobiercą języka C. Praktycznie każdy program napisany w języku C daje się skompilować kompilatorem C++. Nie zapominajcie jednak o tym "++". Wykorzystujcie siłę i klarowność tego języka! Nie stosujcie archaicznych konstrukcji w C. Nie bójcie się programowania obiektowego ... klas, dziedziczenia, metod wirtualnych...
  • Unikaj tworzenia samodzielnych funkcji. W zasadzie powinna być tylko jedna funkcja - "main". Reszta kodu niech będzie zawarta wewnątrz metod poszczególnych klas.
  • Pojęcie, które może mieć wiele instancji np. "użytkownik", "ikona" itp. w bardzo naturalny sposób implementujemy za pomocą klasy. Zmienne (pola) wewnątrz klasy nie powinny być publiczne. Jeśli chcesz zaimplementować właściwość X która może być zmieniana z zewnątrz stwórz prywatną zmienną X i dwie publiczne metody: setX() zmieniającą daną wartość i zwracającą ją x().
  • Pojęcie, które nie powinno mieć więcej niż jednej instancji np. "autostatus" czy "menadżer emotikon" również powinno się implementować za pomocą klasy.
  • Jeśli obiekt twojej klasy X ma być utworzony przy starcie aplikacji i nie jest zależny od innych obiektów (czyli może np. być utworzony jako pierwszy) możesz zaimplementować kod jako zwykłą klasę oraz zadeklarować jedną zmienną klasy X o nazwie np. x będącą tą jedyną instancją klasy (pojęcia).
 xxx.h:
 ------
 class X
 {
       public:
               X();
               void m();
 };
 extern X x;
 xxx.cpp:
 --------
 X::X()
 {
 }
 void X::m()
 {
 }
 X x;


  • (FIXME) Jeśli chcesz, aby z pozostałej części kodu można było kontrolować kiedy obiekt ten będzie utworzony, a kiedy zniszczony powinieneś zadeklarować statyczne (static) publiczne metody create(), destroy() lub on(), off() lub też enable(), disable() w zależności od przeznaczenia tworzonej przez Ciebie klasy. Konstruktor takiej klasy powinien być prywatny. Zabroni to innym developerom utworzenia przez przypadek kolejnej instacji. Wszystkie metody powinny być statyczne i operować na obiekcie Instance.
 xxx.h:
 ------
 class X
 {
       private:
               static X* Instance;
               X();
       public:
               static void create();
               static void destroy();
               static void m();
 };
 xxx.cpp:
 --------
 X::X()
 {
 }
 void X::create()
 {
       if(Instance==NULL)
               Instance=new X();
 }
 void X::delete()
 {
       if(Instance!=NULL)
               delete Instance;
 }
 void X::m()
 {
 }
 X* X::Instance=NULL;

Kadu jest programem opartym o Qt

  • Staraj się wykorzystywać mechanizmy dostarczone przez bibliotekę Qt zamiast funkcji z glibc lub xlib. Używaj np. klasy QFile zamiast funkcji fopen(), fwrite() itp.
  • Używaj mechanizmu sygnałów tam gdzie tylko jest to możliwe i nie powoduje zbytniego zamieszania. Sygnały i sloty to rozwiązania eleganckie i warto z nich korzystać.

Wygląd kodu - zasady składni

  • Wzorując się na standardach Qt, ale również dodając własne, (bardziej rygorystyczne) przyjmujemy, że:
    • w nazwach klas każdy wyraz nazwy łącznie z pierwszym rozpoczynamy wielką literą, np.: PendingMsgs, EmoticonsManager
    • zmienne prywatne w klasach zapisujemy w podobny sposób jak nazwy klas, np.: MainLayout, SomethingEnabled
    • nazwy metod, sygnałów i slotów rozpoczynają się od małej litery, a drugi i kolejne wyrazy nazwy rozpoczynamy wielką literą, np.: activate(), setFocus(), clicked(), encryptionButtonClicked()
    • nazwy argumentów metod piszemy małymi literami, wyrazy oddzielając podkreślnikiem, np.: setSomething(bool enabled), setMarginSize(int margin_size)
  • Wszystkie wcięcia powinny być wykonywane za pomocą tabulacji a nie spacji! Sprawdź ustawienia swojego edytora.
  • Komentarze przed deklaracjami klas i funkcji powinny być otoczone symbolami "/**" i "**/". Kod taki jest zgodny z wymogami programów do automatycznego tworzenia dokumentacji przy użyciu kodu źródłowego (np. kdoc).

Deklaracja klasy (oczywiście nie wszystkie elementy muszą występować):

       /**
               opis klasy
               ...
       **/
       class NazwaKlasy : lista_klas_podstawowych
       {
               Q_OBJECT
               private:
                       ZmiennaPrywatna1
                       ZmiennaPrywatna2
                       ...
                       metodaPrywatna1()
                       metodaPrywatna2()
                       ...
               private slots:
                       /**
                               opis slotu prywatnego 1
                       **/
                       slotPrywatny1()
                       /**
                               opis slotu prywatnego 2
                       **/
                       slotPrywatny2()
                       ...
               protected:
                       ZmiennaChroniona1
                       ZmiennaChroniona2
                       ...
                       /**
                               opis metody chronionej 1
                       **/
                       metodaChroniona1()
                       /**
                               opis metody chronionej 2
                       **/
                       metodaChroniona2()
                       ...
               protected slots:
                       /**
                               opis slotu chronionego 1
                       **/
                       slotChroniony1()
                       /**
                               opis slotu chronionego 2
                       **/
                       slotChroniony2()
                       ...
               public:
                       /**
                               opis publicznego konstruktora 1
                       **/
                       publicznyKonstruktor1()
                       /**
                               opis publicznego konstruktora 2
                       **/
                       publicznyKonstruktor2()
                       ...
                       destruktor()
                       /**
                               opis metody publicznej 1
                       **/
                       metodaPubliczna1()
                       /**
                               opis metody publicznej 2
                       **/
                       metodaPubliczna2()
                       ...
               public slots:
                       /**
                               opis slotu publicznego 1
                       **/
                       slotPubliczny1()
                       /**
                               opis slotu publicznego 2
                       **/
                       slotPubliczny2()
                       ...
               signals:
                       /**
                               opis sygnału 1
                       **/
                       sygnał1()
                       /**
                               opis sygnału 2
                       **/
                       sygnał2()
                       ...
       };


Definiowanie metod:

Kod:

       NazwaKlasy::nazwaMetody(typ argument_1, typ argument2, ...)
       {
               treść funkcji
               ...
       }


Wyrażenie warunkowe

Kod:

       if(warunek)
               instrukcja;
       if(warunek)
       {
               instrukcja 1;
               instrukcja 2;
               ...
       }


Pętla while (for i do/while podobnie)

Kod:

       while(warunek)
               instrukcja;
       while(warunek)
       {
               instrukcja 1;
               instrukcja 2;
               ...
       }

Zasady pracy w grupie nad projektem

  • Jeśli nie masz praw zapisu do Subversion przysyłaj developerom patche, tworzone poleceniem "diff -u". Najlepiej generować je względem najświeższej wersji z Subversion, ale nie jest to wymagane, jeśli w międzyczasie nie było poważnych zmian w kodzie. Patche, które nie nałożą się poprawnie na aktualny kod będą odrzucane.
  • Podczas aktualizowania źródeł w Subversion podawaj w miarę krótkie, lecz sensowne opisy dokonywanych modyfikacji (svn commit -m "opis").
  • Jeśli dokonywana zmiana nie jest tylko poprawką kodu, lecz dotyczy funkcjonalności programu, nie powinieneś podejmować decyzji samodzielnie. Skonsultuj planowaną modyfikację lub rozbudowę z pozostałymi programistami nawet jeśli sprawa wydaje się jasna. Przy mniejszych zmianach (nie wywracających projektu do góry nogami) wystarczy akceptacja któregoś ze "starych wyjadaczy" ;)

Osobiste