Правильное место для инициализации переменных класса?

Где правильное место для инициализации элемента данных класса? У меня есть объявление класса в заголовочном файле, например:

foo.h:

class Foo {
private:
    int myInt;
};

Затем я пытаюсь установить значение myInt в соответствующем файле .cpp:

foo.cpp:

int Foo::myInt = 1;

Я получаю ошибку компилятора для переопределения myInt. Что я делаю неправильно?

Ответы

Ответ 1

У вас есть переменная экземпляра. Каждый экземпляр класса получает свою собственную копию myInt. Место для инициализации - в конструкторе:

class Foo {
private:
    int myInt;
public:
    Foo() : myInt(1) {}
};

Переменная класса - это та, где имеется только одна копия, которая разделяется каждым экземпляром класса. Те могут быть инициализированы, как вы пробовали. (См. Ответ JaredPar для синтаксиса)

Для интегральных значений у вас также есть возможность инициализировать статический const прямо в определении класса:

class Foo {
private:
    static const int myInt = 1;
};

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

Ответ 2

Чтобы продлить ответ Jared, если вы хотите инициализировать его так, как сейчас, вам нужно поместить его в конструктор.

class Foo
{
public:
    Foo(void) :
    myInt(1) // directly construct myInt with 1.
    {
    }

    // works but not preferred:
    /*
    Foo(void)
    {
        myInt = 1; // not preferred because myInt is default constructed then assigned
                   // but with POD types this makes little difference. for consistency
                   // however, it best to put it in the initializer list, as above
                   // Edit, from comment: Also, for const variables and references,
                   // they must be directly constructed with a valid value, so they
                   // must be put in the initializer list.
    }
    */

private:
    int myInt;
};

Ответ 4

Вы пытаетесь инициализировать член экземпляра через статическую конструкцию инициализации. Если вы хотите, чтобы это была переменная уровня класса (статическая), перед ней следует статическое ключевое слово.

class Foo {
private:
  static int myInt;
};

Ответ 5

Переменная класса должна быть помечена как "статическая". Если ваша переменная является переменной экземпляра, а не переменной класса, вы должны инициализировать ее в конструкторе или другом методе.