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" ;)

