Как объявить две разные статические переменные? (С++)

РЕДАКТИРОВАТЬ: объявление их частными было опечаткой, я исправил это:

Что касается другого вопроса, если я объявил статическую переменную в классе, а затем получил от нее класс, есть ли способ объявить статическую переменную как индивидуальную для каждого класса. То есть:

class A:
{
public:
static int x;
};
class B:A
{
public:
const static int x;
};

определяет ли это ДВЕ РАЗНЫЕ статические переменные x, одну для A и одну для B, или я получу ошибку при переопределении x, и если я получу ошибку, как мне создать две отдельные статические переменные?


person Community    schedule 15.06.2009    source источник
comment
лол, я думал, что компилятор ответит на этот вопрос быстрее и раньше, чем кто-либо из нас здесь   -  person kizzx2    schedule 16.06.2009


Ответы (5)


Когда вы используете статические переменные, может быть хорошей идеей явно ссылаться на них:

public class B:A
{
  public const static int x;
  public int foo()
  {
    return B::x;
  }
}

Таким образом, даже если класс «выше» вашего в иерархии решит создать член с таким же именем, это не нарушит ваш код. Точно так же я обычно пытаюсь использовать ключевое слово this при доступе к обычным полям-членам.

Обновлено для использования синтаксиса C++.

person StriplingWarrior    schedule 15.06.2009
comment
Обратите внимание, что это синтаксис Java. Чтобы сделать такую ​​же явную ссылку в C++, вам нужно использовать оператор области видимости, например. Б::х - person Tyler McHenry; 16.06.2009
comment
Что ж, остальная часть окружающего кода по-прежнему не соответствует C++, но я думаю, что спрашивающий сможет перевести, если он достаточно знаком с C++. :) - person Tyler McHenry; 16.06.2009

Это создает две отдельные статические переменные.

person Lyndsey Ferguson    schedule 15.06.2009

Обратите внимание, что вы неявно объявили эти частные:

class A:
{
  private:
  static int x;
};
class B:A
{
  private:
  const static int x;
};

Это означает, что переменные не конкурируют друг с другом.

person Alex Brown    schedule 15.06.2009

Как уже было сказано, это создает две отдельные переменные:

A::x;

// and 

B::x;

На самом деле, если вы попытаетесь использовать только «x» в методе B, будет использоваться только более близкое определение области видимости, пока вы не станете более точным:

#include <iostream>

class A
{
protected:
static int x;

public:
    A() { x = 7; }
};

int A::x = 22;

class B:A
{
static const int x = 42;

public:

    int a_x() const { return A::x; }
    int b_x() const { return B::x; }
    int my_x() const { return x; } // here we get the more local variable, that is B::x.
};

int main()
{
    B b;

    std::cout << "A::x = " << b.a_x() << std::endl;
    std::cout << "B::x = " << b.b_x() << std::endl;
    std::cout << "b's x = " << b.my_x() << std::endl;

    std::cin.ignore();
    return 0;
}

Выходы:

A::x = 7
B::x = 42
b's x = 42

Кто-то упомянул, что доступность может ограничить доступность: приватность базовой переменной не сделает ее доступной для дочернего класса. Однако, если переменная должна быть защищена или общедоступна, используйте явный метод доступа или полагайтесь на правило локальной области, которое я только что продемонстрировал.

person Klaim    schedule 15.06.2009

Если вам нужна статическая переменная, индивидуальная для каждого класса, использующего A, вы можете использовать класс-шаблон.
Например.

template<class T> struct A
{
   A() { ++s_var; }
   static int s_var;
};

template<class T> int A<T>::s_var;

stuct B :A<B> {
  B() { ++s_var; }  // this is a different s_var than the one used by 'C' below
};

struct C : A<C> {
  C() { ++s_var; } // this is a different s_var than the one used by 'B'
};
person Faisal Vali    schedule 15.06.2009