ошибка: ISO C ++ запрещает инициализацию в классе неконстантного статического члена

это заголовочный файл: employee.h

#ifndef EMPLOYEE_H
#define EMPLOYEE_H

#include <iostream>
#include <string>
using namespace std;

class Employee {
public:
Employee(const string &first, const string &last)

Перегруженный конструктор

    : firstName(first),

firstName перегруженный конструктор

      lastName(last)

перегруженный конструктор lastName

    { //The constructor start
++counter;

это добавляет один плюс за каждый созданный объект;

    cout << "Employee constructor for " << firstName
<< ' ' << lastName << " called." << endl;
}

~Employee() {

Destructor
соиЬ << «~ Employee () вызван для» << имя << »
<< Фамилия << епсИ;

Возвращает имя и фамилию каждого объекта

        --counter;

Счетчик минус один

    }

string getFirstName() const {
return firstName;
}

string getLastName() const {
return lastName;
}

static int getCount() {
return counter;
}
private:
string firstName;
string lastName;

static int counter = 0;

Вот где я получил ошибку. Но почему?

};

Основная программа: employee2.cpp

#include <iostream>
#include "employee2.h"using namespace std;

int main()
{
cout << "Number of employees before instantiation of any objects is "<< Employee::getCount() << endl;

Здесь я называю значение счетчика из класса

    {

Начать новый блок области

        Employee e1("Susan", "Bkaer");

Инициализируйте объект e1 из класса Employee

        Employee e2("Robert", "Jones");

Инициализируйте объект e2 из класса Employee

        cout << "Number of employees after objects are instantiated is"<< Employee::getCount();

cout << "\n\nEmployee 1: " << e1.getFirstName() << " " << e1.getLastName()
<< "\nEmployee 2: " << e2.getFirstName() << " " << e2.getLastName()
<< "\n\n";
}

конец блока области

    cout << "\nNUmber of employees after objects are deleted is "<< Employee::getCount() << endl; //shows the counter's value
} //End of Main

В чем проблема?
Я понятия не имею, что не так.
Я много думал, но я не делаю, что не так.

12

Решение

инициализация статического члена counter не должно быть в заголовочном файле.

Измените строку в заголовочном файле на

static int counter;

И добавьте следующую строку в ваш employee.cpp:

int Employee::counter = 0;

Причина в том, что размещение такой инициализации в файле заголовка будет дублировать код инициализации в каждом месте, где включен заголовок.

42

Другие решения

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

// file "Employee.h"#ifndef EMPLOYEE_H
#define EMPLOYEE_H

class Employee {
public:
Employee() {
getCounter()++;
}
~Employee() {
getCounter()--;
}

static auto getCount() -> std::size_t {
return getCounter();
}
private:
// replace counter static field in class context,
//    with counter static variable in function context
static auto getCounter() -> std::size_t& {
static std::size_t counter = 0;
return counter;
}
};

#endif //EMPLOYEE_H

Я взял на себя смелость использовать std::size для представления неотрицательного количества сотрудников и конечный синтаксис возврата для функций.

Сопутствующий тест (ссылка на идеон):

#include "Employee.h"
int main() {
std::cout << "Initial employee count = " << Employee::getCount() << std::endl;
// printed "count = 0"
Employee emp1 {};
std::cout << "Count after an employee created = " << Employee::getCount() << std::endl;
// printed "count = 1"
{
Employee emp2 {};
std::cout << "Count after another employee created = " << Employee::getCount() << std::endl;
// printed "count = 2"}
std::cout << "Count after an employee removed = " << Employee::getCount() << std::endl;
// printed "count = 1"
return 0;
}
1

По вопросам рекламы [email protected]