2009-04-30 5 views
1

Извините, если этот вопрос кажется тривиальным для многих здесь.Запрос на статические переменные-члены класса в C++

В коде на C++ есть что-то, как показано ниже:

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

}//class definition ends 

int Foo::bands; //Note: here its not initialized to any value! 
  1. Почему выше заявление необходимо еще раз, когда «группы» однократно объявлена ​​внутри класса как статический?

  2. Также может ли статическая переменная быть объявлена ​​как переменная частного члена в любом классе?

+0

Это не нужно в этом случае. Вы хотели сделать группы статичными? – jalf

ответ

5

C++ отмечает различие между , объявив и , определяя. bands объявлен в классе, но не определен.

Элемент нестатических данных будет определяться при определении объекта этого типа, но поскольку статический член не является частью какого-либо одного конкретного объекта, ему необходимо его собственное определение.

2

a) Это необходимо, потому что именно так спроектирован язык.

b) Статические переменные инициализируются их конструктором по умолчанию или равны нулю для встроенных типов.

c) Да, они могут быть (и обычно) частными.

0

Это связано с OBJ файлов, как они используются, и как адреса памяти для глобально контекстные переменные, в конечном счете обнаружены в процессе связывания. Объектные файлы содержат адреса всех глобальных данных и функций, определенных в соответствующем cpp. Они откладывают некоторую память соответствующим образом, чтобы рассказать о том, где в этом файле можно найти эти глобальные vars/funcs. Так, например,

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 

Его почти легче подумать, если вы сделали прямо C раньше. В чистом мире C вы делали бы вещи в более традиционном модульном смысле программирования. Ваш модуль будет определен с заголовком и cpp. Заголовок будет определять «общедоступную» переменную, как показано ниже, используя ключевое слово extern, а затем создать экземпляр в 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 

"Экстерн" ключевое слово говорится, что это имя является действительным, и его адрес будет получить разрешение на время соединения. Все, кто включил «foo.h» и захотели использовать глобальную переменную «band», теперь могли ее использовать. Во время соединения, компоновщик выяснил, что полосы существуют в foo.obj. Если вы забыли поместить «int band» в foo.obj, вы получили бы ошибку компоновщика и должны решить ее.

В C++ использование static в объявлении класса i похоже.Вы говорите пользователям, что существует эта вещь, называемая «foo :: bands» и где она будет жить, будет решена во время связи. Позже по линии линкер видит, что в foo.obj существует foo :: bands, и все ссылки на foo :: bands могут быть разрешены.

0

Я понимаю, что вам нужно будет объявить Foo :: bands, если вы планируете использовать его до создания экземпляра своего класса. В принципе, когда вы объявляете статику в классе C++, для всех экземпляров этого класса существует только одна копия этой переменной. Однако вы не можете нормально обращаться к Foo :: band, пока не будет объявлен экземпляр класса.

Например:

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); 
} 
+1

Ваше понимание неверно. Статическая переменная будет существовать, даже если экземпляры классов никогда не создаются. – 2009-04-30 13:53:33

+0

Извините, что я не был ясен, мое намерение состояло в том, чтобы не подразумевать, что переменная не существует - только то, что она обычно недоступна, пока не будет создан экземпляр класса (например, через указатель класса к элементу данных), и как таковой он нужно только создать int Foo :: bands; если он планирует получить доступ к переменной до создания каких-либо экземпляров класса. –

Смежные вопросы