Запрос статических переменных-членов класса в C ++ - PullRequest
1 голос
/ 30 апреля 2009

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

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

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

}//class definition ends

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

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

Ответы [ 5 ]

5 голосов
/ 30 апреля 2009

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

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

2 голосов
/ 30 апреля 2009

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

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

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

0 голосов
/ 30 апреля 2009

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

Например:

Указатели для членов

#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);
}
0 голосов
/ 30 апреля 2009

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

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. В чистом мире Си вы будете делать вещи в более традиционном смысле модульного программирования. Ваш модуль будет определен с заголовком и 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

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

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

0 голосов
/ 30 апреля 2009

Взгляните на этот вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...