Запрос статических переменных-членов класса в C++

StackOverflow https://stackoverflow.com/questions/806846

  •  03-07-2019
  •  | 
  •  

Вопрос

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

В коде C++ есть что-то вроде ниже:

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

}//class definition ends

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

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

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

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

фу.ч

extern int bands; 

foo.cpp

#include "foo.h"
int bands;

фу.объект:

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

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

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

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

Например:

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

#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);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top