Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Thinking in C++
Prev Contents / Index Next

Defining storage for static data members

Because static data has a single piece of storage regardless of how many objects are created, that storage must be defined in a single place. The compiler will not allocate storage for you. The linker will report an error if a static data member is declared but not defined.

The definition must occur outside the class (no inlining is allowed), and only one definition is allowed. Thus, it is common to put it in the implementation file for the class. The syntax sometimes gives people trouble, but it is actually quite logical. For example, if you create a static data member inside a class like this:

class A {
  static int i;
public:
  //...
}; 

Then you must define storage for that static data member in the definition file like this:

int A::i = 1;

If you were to define an ordinary global variable, you would say

int i = 1;

but here, the scope resolution operator and the class name are used to specify A::i.

Some people have trouble with the idea that A::i is private, and yet here’s something that seems to be manipulating it right out in the open. Doesn’t this break the protection mechanism? It’s a completely safe practice for two reasons. First, the only place this initialization is legal is in the definition. Indeed, if the static data were an object with a constructor, you would call the constructor instead of using the = operator. Second, once the definition has been made, the end-user cannot make a second definition – the linker will report an error. And the class creator is forced to create the definition or the code won’t link during testing. This ensures that the definition happens only once and that it’s in the hands of the class creator.

The entire initialization expression for a static member is in the scope of the class. For example,

//: C10:Statinit.cpp
// Scope of static initializer
#include <iostream>
using namespace std;

int x = 100;

class WithStatic {
  static int x;
  static int y;
public:
  void print() const {
    cout << "WithStatic::x = " << x << endl;
    cout << "WithStatic::y = " << y << endl;
  }
};

int WithStatic::x = 1;
int WithStatic::y = x + 1;
// WithStatic::x NOT ::x

int main() {
  WithStatic ws;
  ws.print();
} ///:~

Here, the qualification WithStatic:: extends the scope of WithStatic to the entire definition.

Thinking in C++
Prev Contents / Index Next

 
 
   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire