Постоянная процедура в C , странная ошибка в Visual Studio C 2010?

#c #visual-c -2010

#c #visual-c -2010

Вопрос:

 class a{
public:
    int b;
    static int c;
    virtual void mod() const
    {
        c=4;
    }

};



int _tmain(int argc, _TCHAR* argv[])
{
  a bi;

  return 0;
}
  

Посмотрите на это … После компиляции с использованием компилятора Visual Studio C 2010 я получаю…

cpplearningconsole.obj : ошибка LNK2001: неразрешенный внешний символ «public: static int a::c» (?c @ a @@2HA)

Я предполагаю, что это ошибка компилятора. Для меня реальный вопрос заключается в следующем. Должен ли mod иметь возможность изменять переменную c, если она имеет значение const?

Спасибо.

Комментарии:

1. Это не ошибка компилятора… Вы объявили статический элемент c , но нигде его не определили.

2. mod может быть const и изменять значение c , потому что c не является членом экземпляра (поскольку он статичен), который mod вызывается, поэтому экземпляр не изменяется.

3. mod определен в классе так же, как и b, почему не c? Где в этом логика?

4. b является обычным членом класса, следовательно, создается, когда экземпляры класса являются. Резервировать для нее хранилище не нужно. mod это функция. Вы предоставили тело для функции внутри класса, то есть вы ее определили. Если бы вы просто использовали virtual void mod() const; вместо тела, вы бы получили аналогичную ошибку ссылки из-за отсутствия функции (возможно, вам придется вызвать функцию, прежде чем компоновщик заметит ее отсутствие).

5. @Aftershock: Правило 1: это никогда не ошибка компилятора. Правило 2: (Только для экспертов) это никогда не ошибка компилятора. (Хотя я признаю, что в VS есть некоторые ошибки, вы вряд ли когда-нибудь столкнетесь с одной из них)

Ответ №1:

Вы только что объявили статическую переменную в определении класса, вам нужно определить ее в процессе выполнения int a::c = 0; .

Комментарии:

1. Действительно, и ошибка не имеет никакого отношения к функции-члену, являющейся const , и это, конечно, не ошибка компилятора.

Ответ №2:

Это:

cpplearningconsole.obj : ошибка LNK2001: неразрешенный внешний символ «public: static int a::c» (?c @ a @@2HA)

Это не сообщение компилятора, это сообщение компоновщика. Вы получаете это, потому что, хотя вы объявили элемент c , вы его не определили. Статические элементы должны быть определены только в одном исходном файле, чтобы они могли быть созданы. Что-то вроде:

 int a::c = 0;
  

Что касается вашего второго вопроса, в объявлении функции как const указано, что она не изменяет объект, к которому она вызывается. Ваша mod функция не изменяет объект, она изменяет статический элемент. Вот почему вы не получаете ошибку компилятора.

Ответ №3:

Вы должны добавить правильное определение для вашей переменной member, в классе у вас есть только объявление. В вашем cpp или сразу после объявления класса (вне его) добавьте:

int a::c = 0;

Ответ №4:

Чтобы ответить на ваш другой вопрос:

c является общедоступным статическим членом вашего класса. Любой может изменить ее значение, так почему бы и нет mod() ?