Question

Sorry if this question seems trivial to many here.

In a C++ code there is something as below:

class Foo
{
public:
   static int bands;
   ...
   ...
private:
   ...
   ...

}//class definition ends

int Foo::bands; //Note: here its not initialized to any value!
  1. Why is the above statement needed again when 'bands' is once declared inside the class as static?

  2. Also can a static variable be declared as a private member variable in any class?

Was it helpful?

Solution

C++ notes a distinction between declaring and defining. bands is declared within the class, but not defined.

A non-static data member would be defined when you define an object of that type, but since a static member is not a part of any one specific object, it needs it's own definition.

OTHER TIPS

a) It's needed because that's the way the languge is designed.

b) Static variables are initialized by their default constructor, or to zero for built-in types.

c) Yes, they can be (and usually are) private.

Take a look at this question.

It has to do with obj files, how they are used, and how memory addresses for globally scoped variables are ultimately discovered through the linking process. Object files contain the addresses of all global data and functions defined in the corresponding cpp. They layout some memory in a relative fashion to tell the liker where in that file these global vars/funcs can be found. So for example

function doFoo can be found 0 bytes from beginning of this file
int foo::bands can be found 12 bytes from beginning of this file
etc

Its almost easier to think about if you've done straight C before. In a pure C world you would do things in a more traditional modular programming sense. Your module would be defined with a header and a cpp. The header would define a "public" variable like below, using the extern keyword, then instantiate it in the cpp.

foo.h

extern int bands; 

foo.cpp

#include "foo.h"
int bands;

foo.obj:

int bands can be found 0 bytes from the beginning of this file

The "extern" keyword states that this name is valid and its address will get resolved at link time. Everyone that included "foo.h" and wanted to use the "bands" global variable had could now use it. At link time, the linker would figure out that bands existed in the foo.obj. If you forgot to put "int bands" in foo.obj, you'd get a linker error, and have to go resolve it.

In C++ using static in a class declaration i similar. You are telling the users that there exists this thing called "foo::bands" and where it will live will get resolved at link time. Later down the line, the linker sees that in foo.obj, foo::bands exists, and all references to foo::bands can be resolved.

My understanding is that you would only need to declare Foo::bands if you planned on using it prior to ever creating an instance of your class. Basically, when you declare a static in a C++ class then only one copy of that variable exists for all instances of that class. However, you can't normally access Foo::bands until an instance of the class is declared.

For example:

Pointers to Members

#include <iostream>
using namespace std;

class X {
public:
  int a;
  void f(int b) {
    cout << "The value of b is "<< b << endl;
  }
};

int main() {

  // declare pointer to data member
  int X::*ptiptr = &X::a;

  // declare a pointer to member function
  void (X::* ptfptr) (int) = &X::f;

  // create an object of class type X
  X xobject;

  // initialize data member
  xobject.*ptiptr = 10;

  cout << "The value of a is " << xobject.*ptiptr << endl;

  // call member function
  (xobject.*ptfptr) (20);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top