Page suivante Page précédente Table des matières
Approchant de la fin de ce manuel, j'aimerais résumer plusieurs points auxquels les programmeurs devraient être vigilants pendant le codage. Ceux-ci sont principalement des astuces de programmation C++ ayant trait à la programmation KDE et Qt en particulier et sont partiellement issus du Centre du Développeur KDE que vous pouvez trouver sur Internet à l'adresse http://www.kde.org, d'autres sont le fruit de mon expérience personnelle.
Tout d'abord, lorsque vous créez des fichiers sources, vous devriez toujours utiliser des noms de fichiers en minuscules. KDevelop supporte ceci si vous utilisez l'auto-suggestion de noms de fichiers. Cela permet aux autres développeurs de se souvenir plus facilement des fichiers sources à rechercher lorsqu'ils doivent déboguer votre application.
Il est conseillé que les noms de classes des projets KDE respectent ces règles :
KMyWidget
pour un widget spécifique à une application ;myWidgetPointer()
;get
. Vous devriez lui préférer un nom descriptif.
Exemple : b_myboolean
est un champ privé. La méthode renvoyant la valeur
actuelle serait par exemple myBoolean()
.
Vous devez éviter de coder tout chemin en dur, et utiliser les Standards du
Système de Fichiers de KDE. Vous avez juste à vérifier le chemin d'installation
de vos fichiers par les macros de Makefile.am
comme décrit dans le présent
manuel. Au sein du code, vous devriez utiliser les méthodes de
KApplication
pour extraire le chemin réel.
Autre point déjà mentionné, la documentation des classes. Vous devriez utiliser
les règles de formatage de KDoc
telles qu'elles sont utilisées par tous les
développeurs KDE pour documenter leurs classes. Vous devriez ajouter au moins
une ligne à chacun des membres de vos classes pour que vous puissiez vous
souvenir de leur but et pour que les autres puissent réutiliser votre code.
La réutilisation du code par la GPL est bien plus sensée si vous savez où
trouver une solution existante et si les classes sont documentées. La Référence
de la Bibliothèque Qt est un bon exemple d'interfaces bien documentées, bien
qu'elle n'utilise pas KDoc
.
new
pour créer des widgetsAu sein de votre implantation, vous devriez toujours préférer la création
massive de widgets avec new
. La bibliothèque Qt a la bonne habitude
de supprimer automatiquement tous les widgets fils créés avec new
, vous
n'avez donc pas à utiliser delete
dans ces cas. C'est une des
fonctionnalités pratiques des plus importantes de Qt et vous devriez en user
et en abuser.
Quand vient le moment de déboguer, vous devriez utiliser les macros fournies
par KDebug
. Celles-ci sont similaires aux macros Qt, mais peuvent être
obtenues par CTRL+SHIFT+F12. Voir
Référence des Bibliothèques KDE pour plus d'informations sur le
filtrage d'évenements de ces macros. Vous pourriez aussi utiliser
assert()
, mais vous devriez essayer d'être logique dans votre code de déboguage.
const
Par la suite, vous devriez utiliser des déclarations const
pour les méthodes
qui ne devraient changer aucun champ privé. Ce serait le cas pour toutes les
méthodes qui retournent seulement la valeur actuelle d'un champ privé. Cela
permet d'éviter de modifier une valeur accidentellement et de détecter de telles
erreurs dès la compilation. Maintenant, pour l'initialisation des membres const
vous devriez combiner const avec static
et initialiser la valeur en dehors
du constructeur, comme ceci :
class foo {
static const int value;
};
const foo::value = 10;
Le C++ ANSI autorise l'initialisation du champ dans le constructeur mais vous
devriez l'éviter car certains compilateurs n'offrent pas cette fonctionnalité.
Comme nous l'avons vu dans la section
Interaction avec l'Utilisateur, vous devriez conserver les droits d'accès
et la déclaration par virtual
lorsque vous surchargez des méthodes virtuelles.
Tout au moins, vous ne devriez pas réduire l'accès d'une méthode virtuelle de
protégé à privé.
Les en-têtes de classe doivent être inclus lorsque vous déréférencez n'importe quel objet ou instance de classe dans votre code source. Cela signifie que si votre classe utilise un membre d'une autre classe, vous devriez remplacer la directive #include par une déclaration anticipée de la classe. Par exemple, au lieu de :
#include <qpushbutton.h>
class KMyWidget:public QWidget
{
private:
QPushButton* ok_button;
};
déclarez seulement la classe QPushButton
dans le fichier d'en-tête :
class QPushButton;
class KMyWidget:public QWidget
{
private:
QPushButton* ok_button;
};
et placez la directive d'inclusion dans le fichier source correspondant
où, par exemple, l'instance ok_button
est déréférencée avec une
méthode de la classe QPushButton
. Cela permet de gagner du temps
à la compilation, spécialement si vous utilisez des instances de classes
sur lesquelles vous êtes en train de travailler. Le compilateur recompilera
tous les sources qui incluent le fichier d'en-tête si vous avez effectué
des modifications à l'interface de la classe, c'est pourquoi un simple
ajout d'une méthode qui retourne seulement une valeur interne provoquera
le recompilation de tous les sources qui incluent le fichier d'en-tête
de cette classe.
Vous devriez aussi omettre les paramètres formels des méthodes qui
ne nécessitent pas forcément ce paramètre pour fonctionner. Cela évite
les avertissements de paramètre inutilisé
de votre compilateur
quand il voit une méthode qui attend un paramètre formel mais
ne l'utilise pas dans son implantation. Généralement, vous définirez
des arguments par défaut pour plusieurs méthodes. Ils devraient
toujours être placés dans la déclaration du membre de la classe au
lieu de les définir dans l'implantation des méthodes.
config.h
Les projets KDevelop comme tout autre projet qui utilise autoconf
pour créer les script configure
produisent un fichier config.h
après l'exécution du script configure
sur la machine cible.
Les valeurs trouvées par configure
sont listées dedans et
peuvent être utilisées dans le code source. La directive
pour inclure le fichier config.h
est :
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
Une des entrées de config.h
les plus couramment utilisées est probablement
le définition du type bool
pour les compilateurs qui ne respectent pas la
norme la plus récente du C++ ANSI.
0
au lieu de NULL
Vous devriez toujours utiliser directement 0
au lieu de NULL
pour les valeurs prédéfinies comme le font les bibliothèques de KDE
et Qt. Cela améliore la portabilité de vos applications pour différents
compilateurs qui ont des problèmes avec NULL
.
Vous devriez toujours déclarer les instances temporaires avant de les utiliser. En général, cela est considéré comme étant meilleur. Par exemple :
// Ne faites pas :
for( int i=0; i<n; i++){
// faire quelque chose
};
// Mais écrivez :
int i;
for(i=0; i<n; i++){
// faire quelque chose
};
Cela est aussi valable pour les variables temporaires dans les appels de fonctions :
// Ne faites pas :
setColor( &(QColor(black)) );
// Mais écrivez :
QColor color(black);
setColor( &color );
Comme les projets KDevelop utilisent les outils GNU pour créer les projets, vous êtes sûr que votre application fonctionnera sur presque tous les systèmes Unix. Cependant, vous pouvez rencontrer des problèmes lors de la compilation de votre application sur un autre Unix parce que les fichiers d'en-tête sont situés à des endroits différents ou bien que vous avez besoin d'une autre implantation, spécialement lorsque vous utilisez des fonctions de bas niveau de l'OS qui peuvent être différentes d'un système à l'autre.
En programmant avec C++ et Qt/KDE, vous avez du remarquer que les classes de Qt contiennent un grand ensemble de fonctionnalités qui sont déjà indépendantes du compilateur et de l'OS et rendent les choses plus simples, des chaînes de caractères (QString) à la lecture/écriture de fichiers (QFile) ; en utilisant Qt, vous rendez donc obsolètes la plupart des spécificités des systèmes d'exploitation.
Néanmoins, si vous utilisez Qt et que vous avez besoin d'utiliser
des #defines pour votre application, vous devriez inclure
qglobal.h
et utiliser les #defines qui y sont
déjà prédéfinis pour différents systèmes d'exploitation et
compilateurs, comme ci-dessous.
Au lieu de laisser les distributeurs d'OS appliquer des correctifs à votre application (comme beaucoup le font pour construire des paquetages rpm ou autre), vous devriez utiliser des defines pour les sections qui sont spécifiques au système d'exploitation (mais vous n'avez pas besoin d'utiliser l'option -D à la compilation, les définitions de systèmes d'exploitation sont automatiquement prises en compte). La liste ci-dessous définit les systèmes disponibles et leurs définitions (les defines supplémentaires sont entre parenthèses) :
#ifdef _AIX
#if defined(bsdi) || defined(__bsdi__)
#if defined (ultrix) || defined(__ultrix) || defined(__ultrix__)
#if defined(DGUX)
#ifdef __FreeBSD__
#if defined(__GNU__)
#if defined (hpux) || defined (__hpux) || defined (__hpux__)
#if defined(linux) || defined(__linux) || defined(__linux__)
#ifdef __NetBSD__
#ifdef __OpenBSD__
#if defined(__osf__)
#if defined(__QNX__)
#if defined(_UNIXWARE)
#if defined(sco) || defined(_UNIXWARE7)
#if defined(_SCO_DS) || defined(M_UNIX) || defined(M_XENIX)
#if defined(sgi) || defined(__sgi)
#if defined (sun) || defined (__sun) || defined (__sun__)
#if defined (_OS_SUN_) || defined (__SVR4)
Page suivante Page précédente Table des matières