Как получить доступ к статическим членам класса?
Я начинаю изучать С++ и Qt, но иногда самый простой код, который я вставляю из книги, приводит к ошибкам.
Я использую g++4.4.2
в Ubuntu 10.04 с IDE QtCreator. Есть ли разница между синтаксисом компилятора g++ и другими компиляторами? Например, когда я пытаюсь получить доступ к статическим членам, что-то всегда идет не так.
#include <iostream>
using namespace std;
class A
{
public:
static int x;
static int getX() {return x;}
};
int main()
{
int A::x = 100; // error: invalid use of qualified-name 'A::x'
cout<<A::getX(); // error: : undefined reference to 'A::x'
return 0;
}
Я думаю, что это точно так же, как объявлено здесь и здесь (не так ли?). Итак, что не так с вышеуказанным кодом?
Ответы
Ответ 1
Вы объявили статические члены точными, но не определили их в любом месте.
В основном то, что вы сказали "существует некоторый статический член", но никогда не выделяйте для него некоторую память, вам нужно:
int A::x = 100;
Где-то вне класса, а не внутри основного.
Ответ 2
Раздел [9.4.2]
Элементы статических данных
Объявление статического члена данных в его определении класса не является определением и может иметь неполный тип, отличный от cv-qualoid void. Определение для статического члена данных должно появиться в области пространства имен, охватывающей определение класса участников. В определении в области пространства имен имя статического члена данных должно быть присвоено его именем класса с помощью оператора ::
Ответ 3
Try:
#include <iostream>
using namespace std;
class A
{
public:
// This declares it.
static int x;
static int getX(){return x;}
};
// Now you need an create the object so
// This must be done in once source file (at file scope level)
int A::x = 100;
int main()
{
A::x = 200;
// Note no int here. You can modify it
cout<<A::getX(); // Should work
return 0;
}
Ответ 4
Определение статических переменных-членов должно находиться в области содержимого файла, то есть вне всех функций и т.д.
Ответ 5
Попробуйте этот пример:
#include<iostream>
using namespace std;
class check
{
static int a;
public:
void change();
} ;
int check::a=10;
void check::change()
{
a++;
cout<<a<<"\n";
}
int main()
{
int i,j;
check c;
check b;
c.change();
b.change();
return 0;
}
Ответ 6
Теперь вы определили, как использовать статические члены класса. Я советую вам использовать их только в следующих случаях:
-
Для использования в шаблонах. Таким образом, в вашем примере вы могли бы использовать GetX() в разных классах и в шаблоне где-то вы использовали бы
template< typename T >
int func()
{
return T::GetX();
}
хотя очевидно более сложный. Но здесь ваша статическая функция, находящаяся в классе, служит цели.
-
Если функция нуждается в доступе к классу, то есть к частным членам. Вы можете сделать его другом, но вы также можете сделать его статичным. Часто случай в обратных вызовах.
В остальное время вы, вероятно, можете использовать функции и переменные уровня единицы компиляции, которые имеют преимущество в том, чтобы вытащить ваших членов из заголовка (особенно, если они являются частными). Чем меньше деталей реализации, тем лучше.
Ответ 7
Случай 1: статическая переменная
Как мы все знаем, определение статической переменной внутри класса, которое вызовет ошибку компиляции. Например. ниже
class Stats
{
public:
static int AtkStats[3];
*static int a =20;* // Error: defining a value for static variable
};
int Stats::AtkStats[3] = {10, 0, 0};
Вывод:
error: ISO C++ forbids in-class initialization of non-const static member 'Stats::a'
Случай 2: статическая переменная const
Для статической переменной const мы можем определить значение внутри класса или внешнего класса.
class Stats
{
public:
static const int AtkStats[3];
static const int a =20; // Success: defining a value for a const static
};
const int Stats::AtkStats[3] = {10, 0, 0};
const int Stats::a = 20; // we can define outside also
Вывод:
Compilation success.