<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2002/REC-xhtml1-20020801/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>KDE library code guidelines</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" media="screen" type="text/css" title="Default Layout" href="http://developer.kde.org/media/styles/standard.css" />
<style type="text/css" >
pre { background-color: #F6F2FF; padding: 1ex; color: black;}
.comment { color:#555; }
</style>
</head>
<body id="developerkdeorg" >
<div id="content">
<h1>KDE library code guidelines</h1>
<h2>Introduction</h2>
<p>This document describes some of the recommended conventions that should be applied in the KDE libraries (not applications).
Respecting these guidelines helps create a consistant API and also may help ease maintainence of the libraries later.
While these conventions are not mandatory, they are important guidelines, and should be respected unless you have a good reason to disregard them.</p>
<p>As an introduction, you should read the document <a href="http://doc.trolltech.com/qq/qq13-apis.html">Designing Qt-Style C++ APIs</a></p>
<h2>Naming conventions</h2>
<p>In KDE, we follow the same naming conventions as Qt, with a few exceptions.</p>
<p>Class names starts with a capital <code>K</code>. The rest is in camel case. Function names starts with a lower case, but the first letter of each successive word is capitalized.</p>
<p>Unless dealing with central libraries (kdecore, kdeui), classes should be in the library namespace.
In that case, it is the namespace which starts with <code>K</code> and the classes inside may not start with it.
New libraries should choose their namespace.</p>
<p>The prefix '<code>set</code>' is used for setters, but the prefix '<code>get</code>' is <b>not</b> used for accessors. Accessors are simply named with the name of the property they access. The exception is for accessors of a boolean which may start with the prefix '<code>is</code>'.
<em>private slots</em> may start with the prefix <code>slot</code> but it's not required</p>
<p>Acronyms are lowercased too. </p><b>Example:</b> <code>KUrl</code> instead of <code>KURL</code> and <code>isNssEnabled</code> instead of <code>isNSSEnabled</code> </p>
<p>Accessors should usually be <code>const</code>.</p>
<p>This example shows some possible functions names</p>
<pre>
<b class="keyword">public:</b>
void setColor( const QColor& c);
QColor color() const;
void setDirty( bool b );
bool isDirty() const;
<b class="keyword">private Q_SLOTS:</b>
void slotParentChanged();
</pre>
<p>Make one public class per <code>.h</code> file. Add the <code>_EXPORT</code> macro related to the library they are in.</p>
<p>Private classes should be declared in a the <code>.cpp</code> file, or in a <code>_p.h</code> file</p>
<h2>D-Pointers</h2>
<p>In order to more easily maintain binary compatibility, there shouldn't be private members in a public class.</p>
<p>For more information about binary compatibility, read <a href="http://developer.kde.org/documentation/other/binarycompatibility.html">Binary Compatibility Issues With C++</a>.</p>
<p>By convention, the private class will be called <code>Private</code> and will be in the class definition.</p>
<pre>
<b class="keyword">class</b> KFoo
{
<b class="keyword">public:</b>
<i class="comment">/* public members */</i>
<b class="keyword">private:</b>
<b class="keyword">class</b> Private;
Private * const d;
};
</pre>
<pre>
<b class="keyword">class</b> KFoo::Private
{
<b class="keyword">public:</b>
int someInteger;
}
KFoo::KFoo() : d(new Private)
{
<i class="comment">/* ... */</i>
}
KFoo::~KFoo()
{
<b class="keyword">delete</b> d;
}
</pre>
<p>Notice that the member <code>d</code> is <b><code>const</code></b> to avoid modifying it by mistake.</p>
<p>If you are implementing an implicitly shared class, you should consider using <code>QSharedData</code> and <code>QSharedDataPointer</code> for <code>d</code>.<br/>
Use <code>QAtomic</code> for reference counting. Don't try to implement your own refcounting with integers.</p>
<p>Sometimes, complex code may be moved to a member method of the Private class itself. Doing this may give the compiler an extra register to optimize the code,
since you won't be using "d" all the time.</p>
<h2>Inline code</h2>
<p>For binary compatibility reasons, try to avoid inline code in headers. Specifically no inline constructor or destructor.</p>
<p>If ever you add inline code please note the following:</p>
<ul><li>Code must compile with <code>QT_ASCII_NO_CAST</code>. So don't forget <code>QLatin1String.</code></li>
<li>No C casts in the header. Use <code>static_cast</code> if types are known. Use <code>qobject_cast</code> instead of <code>dynamic_cast</code> if types are QObject based.
<code>dynamic_cast</code> is not only slower, but is also unreliable across shared libraries.</li>
<li>In General, check your code for <a href="http://developer.kde.org/documentation/other/mistakes.html">common mistakes</a>.</li>
</ul>
<p>These recommendations are also true for code that are not in headers</p>
<h2>Flags</h2>
<p>We should try to avoid meaningless booleans parameters in functions.</p>
<p>This is an example of a bad boolean argument</p>
<p>
<code>static QString KApplication::makeStdCaption( const QString &userCaption,
bool withAppName = true, bool modified = false );</code>
</p>
<p>Because when you read code that uses the above function, you can't easily know the significance of the parameters</p>
<p>
<code>window->setCaption( KApplication::makeStdCaption( "Document Foo" , true , true ) );</code>
</p>
<p>The solution is to use <a href="http://doc.trolltech.com/4.1/qflags.html">QFlags</a>.
If the options only apply to one function, call the enum <code>FunctionNameOption</code> and the QFlags typedef <code>FunctionNameOptions</code>. Do that even if there is only one option, this will allow you to add more options later and keep the binary compatibility.</p>
<p>So a better API would be:</p>
<pre>
<b class="keyword">class</b> KApplication
{
<b class="keyword">public:</b>
<i class="comment">/* [...] */</i>
<b class="keyword">enum</b> MakeStandardCaptionOption
{
<i class="comment">/**
* Indicates that the method shall include the application name
*/</i>
WithApplicationName = 0x01,
<i class="comment">/**
* If set, a 'modified' sign will be included in the returned string.
*/</i>
Modified = 0x02
};
Q_DECLARE_FLAGS( MakeStandardCaptionOptions, MakeStandardCaptionOption)
<i class="comment">/**
* Builds a caption using a standard layout.
*
* @param userCaption The caption string you want to display
* @param options a set of flags from MakeStandartCaptionOption
*/</i>
static QString makeStandardCaption( const QString& userCaption,
const MakeStandardCaptionOption& options = WithApplicationName );
<i class="comment">/* [...] */</i>
};
Q_DECLARE_OPERATORS_FOR_FLAGS(KApplication::MakeStandardCaptionOptions)
</pre>
<h2>Const references</h2>
<p>Each object parameter that is not a basic type (<code>int, float, bool, enum, </code> or pointers) should be passed by constant reference.
This is faster, because it is not required to do a copy of the object. Do that even for object that are already implicitly shared, like QString</p>
<pre>
QString myMethod( const QString& foo, const QPixmap& bar, int number);
</pre>
<h2>Signals and slots</h2>
<p>In the libraries, use <code><b class="keyword">Q_SIGNALS:</b></code> and <code><b class="keyword">Q_SLOTS:</b></code> instead of <code>signals:</code> and <code>slots:</code> <br/>
They are syntactically equivalent and should be used to avoid conflicts with <a href="http://www.boost.org/">boost</a> signals, and with python's use of "slots" in its headers.</p>
<h2>Explicit constructors</h2>
<p>For each constructor, check if you should make the constructor <code><b class="keyword">explicit</b></code> in order to minimize wrong use of the constructor.</p>
<p>Basically, each constructor that may take only one arguement should be marked <code>explicit</code> unless the whole point of the constructor is to allow implicit casting</p>
<h2>Avoid including other headers in headers</h2>
<p>Try to reduce as much as possible the number of includes in header files.
This will generally help reduce the compilation time, especially for developers when just one header has been modified.
It may also avoid errors that can be caused by conflicts between headers.
</p>
<p>If an object in the class is only used by pointer or by reference, it is not required to include the header for that object. Instead, just add a forward declaration before the class.<br/>
In this example, the class KFoo uses KBar by reference, so we don't need to include KBar's header</p>
<pre>
#include <kfoobase.h>
<b class="keyword">class</b> KBar;
<b class="keyword">class</b> KFoo : <b class="keyword">public</b> KFooBase
{
<b class="keyword">public:</b>
<i class="comment">/* [...] */</i>
void myMethod( const & KBar );
};
</pre>
<h2>Static objects</h2>
<p>Global static objects in libraries should be avoided. You never
know when the constructor will be run or if it will be run at all.</p>
<h4>Wrong</h4>
<pre>
static QString foo; <i class="comment">// wrong - object might not be constructed</i>
static QString bar("hello"); <i class="comment">// as above</i>
static int foo = myInitializer(); <i class="comment">// myInitializer() might not be called </i>
</pre>
<h4>Correct</h4>
<pre>
static const int i = 42;
static const int ii[3] = {1, 2, 3};
static const char myString[] = "hello";
static const MyStruct s = {3, 4.4, "hello"};
</pre>
<p>You can use <code>Q_GLOBAL_STATIC</code> to create global static objects which will be initialized the first time you use them.</p>
<h2>Documentation</h2>
<p>Every class and method should be well documented. Read the <a href="http://developer.kde.org/policies/documentationpolicy.php">KDE Library Documentation Policy</a> for the guidelines to follow when documenting your code.</p>
<p>Also don't forget the license headers and copyrights in each file. As stated in the <a href="http://developer.kde.org/policies/licensepolicy.html">Licensing Policy</a>, kdelibs code must be licensed under the LGPL, BSD, or X11 license. </p>
<p style="text-align:right">
<small> Author: <em> Olivier Goffart <a href="mailto:ogoffart@kde.org">ogoffart@kde.org</a></em><br/>
<em>2006-03-05</em></small></p>
</div>
</body>
</html>