20.4.3.  namespace, static objects and extern

[ fromfile: namespaces.xml id: namespace-example ]

Objects declared inside namespaces are implicitly static, meaning that they are created once for the entire application. The initialization of a static object must exist in only one C++ module. To declare a static (global or namespace) object without defining it, use the keyword extern.[119] Example 20.17 shows how to declare namespace variables.

Example 20.17. src/qstd/qstd.h

[ . . . . ]
namespace qstd {

     // declared but not defined:
     extern QTextStream cout;
     extern QTextStream cin;
     extern QTextStream cerr;

     // function declarations:
     bool yes(QString yesNoQuestion);
     bool more(QString prompt);
     int promptInt(int base = 10);
     double promptDouble();
     void promptOutputFile(QFile& outfile);
     void promptInputFile(QFile& infile);
};
[ . . . . ]

<include src="src/qstd/qstd.h" href="src/qstd/qstd.h" role="textbook" id="qstdh2" mode="cpp"/>


Functions and classes can be declared or defined in the header file of a namespace. But each top level object (that is not local to a namespace function) in a namespace must be defined in a .cpp file, as shown in Example 20.18 if it has not been defined in the header file.

Example 20.18. src/qstd/qstd.cpp

[ . . . . ]
QTextStream qstd::cout(stdout, QIODevice::WriteOnly);
QTextStream qstd::cin(stdin, QIODevice::ReadOnly);
QTextStream qstd::cerr(stderr, QIODevice::WriteOnly);

/* Namespace members are like static class members */
bool qstd::yes(QString question) {
    QString ans;
    cout << QString(" %1 [y/n]? ").arg(question);
    cout.flush();
    ans = cin.readLine();
    return (ans.startsWith("Y", Qt::CaseInsensitive));
}

<include src="src/qstd/qstd.cpp" segid="namespace" href="src/qstd/qstd.cpp" role="textbook" mode="cpp" id="qstdcpp2"/>




[119] Even inside namespaces!