2016-10-02 4 views
0

Я пытаюсь подсчитать количество экземпляров класса, изменяя статический элемент данных:Изменение статического члена данных в конструкторе класса


class C 
{ 
public: 
    static unsigned int i; 
    C(){i++;} 
}; 

это показывает ошибку:
Main.obj: ошибка LNK2001: неразрешенный внешний символ "public: static unsigned char C :: i" (? i @ C @@ 2EA)

, пожалуйста, помогите мне здесь, отредактировав этот код для соответствующего функционирования или сообщив мне решение этой проблемы без использование любой глобальной переменной.
Ваши ответы будут оценены.
Спасибо.

+0

просто добавьте 'unsigned int C :: i = 0;' после объявления класса и это будет работать –

+0

Также http://stackoverflow.com/questions/15845745/lnk2001-error-when-accessing-static-variables- c, http://stackoverflow.com/questions/16049306/error-lnk2001-unresolved-external-symbol-private-static-class и многие другие. – AnT

ответ

0

Прямой элемент статических данных, которому назначено значение определение. В основном определение выделяет память. Идет так:

class C 
{ 
private: 
    static int i; // pure declaration 

public: 
    static auto n_instances() -> int { return i; } 
    ~C() { --i; } 
    C(){ ++i; } 
    C(C const&) { ++i; } 
}; 

int C::i; // definition 

В заголовочном файле, который является непрактичным (если заголовок используются в нескольких единицах трансляции будет нарушение Одно Определения Правило, с компоновщик жалуется), так, то вы можете использовать следующая методика:

class C 
{ 
private: 
    static auto n() 
     -> int& 
    { 
     static int the_count = 0; 
     return the_count; 
    } 
public: 
    static auto n_instances() -> int { return n(); } 
    ~C() { --n(); } 
    C(){ ++n(); } 
    C(C const&) { ++n(); } 
}; 

Есть и другие способы сделать это, в том числе шаблона трюка и 17 inline C++ данных.

Я решил использовать int вместо unsigned потому int хороша для целых чисел , в то время как unsigned хорошо для вещей немного уровня, но не наоборот.

Отказ от ответственности: код не тронут компилятором.

+0

Почему «автоматический» материал вместо более короткого и более легкого для чтения 'static int & n() {static int n; return n; } '? – 6502

+0

@ Спасибо: Спасибо, что отвечает на мой вопрос и полезен во многих подобных ситуациях. –

+0

@ 6502: Синтаксис объявления старой функции «очень ограниченная область применимости полностью покрывается новым синтаксисом. Глупо использовать два синтаксиса для одного и того же. Я не согласен с удобочитаемостью; напротив, старый синтаксис сосет wrt. читабельность, особенно с более длинными выражениями шаблонов для типа возвращаемого значения (также с необходимостью присвоить тип возврата, который имеет класс). –

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