Thursday, January 10, 2008

Static members

From C++ Faqs book.
Static data members must be explicitly defined in exactly one source file.

class Fred {
public:
static int x_; <-- 1
};

(1) Declare (not define) static member Fred::x_

The linker generates an error ("Fred::x_ is not defined") unless (exactly) one of the source files defines Fred::x_. This definition is normally done in the class's source file, such as file Fred.cpp:

#include "Fred.hpp"
int Fred::x_ = 42; <-- 1

(1) Define static member Fred::x_

Note that the explicit initializer (= 42 in the example) is optional. That is, the line could be changed to

int Fred::x_; <-- 1

(1) Initialize Fred::x_ to 0

Note that even when the static data member is private: or protected:, it must still be explicitly defined as shown in one of the two examples.

class Fred{
public:
static void f();
void g();
static int x_;
};
// int Fred::x_; // default 0. or
// int Fred::x_ = 2;
void Fred::f()
{
printf("f()\n");
}
void Fred::g()
{
}
int main()
{
Fred abc;
abc.x_ = 2; // Wrong. Link error: no define
Fred fr;
Fred::f(); // OK
Fred::g(); // wrong
fr.f(); // wrong(?)
fr.g(); // OK
return 0;
}

Calls to static member functions should be coded as Classname::staticMember() rather than as object.staticMember() or ptr->staticMember().

How is a const static data member initialized?

Here is a sample header file, Fred.hpp.

#include <string>
using namespace std;
class Barney { };

class Fred {
public:
// ...
private:
static const int i_ = 42; <-- 1
static const char c_ = 'z'; <-- 1
static const float x_; <-- 2
static const string s_; <-- 2
static const Barney b_; <-- 2
};

(1) Integral data types can be initialized in the class body proper
(2) Nonintegral data types must be defined in the source file, not in the class body proper

Here is corresponding source file, Fred.cpp.

#include "Fred.hpp"

const float Fred::x_ = 3.14;
const string Fred::s_ = "Hello";
const Barney Fred::b_;

No comments:

Post a Comment