error: ISO C++ forbids in-class initialization of non-const static member

56,474

Solution 1

The initialization of the static member counter must not be in the header file.

Change the line in the header file to

static int counter;

And add the following line to your employee.cpp:

int Employee::counter = 0;

Reason is that putting such an initialization in the header file would duplicate the initialization code in every place where the header is included.

Solution 2

According to a similar SO answer there is another approach, in particular suited for your current implementation (header-only library):

// 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

I took the liberty to use std::size for representing the non-negative employee count and trailing return syntax for functions.

Accompanying test (ideone link):

#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;
}
Share:
56,474

Related videos on Youtube

mishelashala
Author by

mishelashala

JavaScript Developer.

Updated on March 14, 2020

Comments

  • mishelashala
    mishelashala about 4 years

    this is the header file: 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) 
    

    Overloaded Constructor

        : firstName(first), 
    

    firstName overloaded constructor

          lastName(last) 
    

    lastName overloaded constructor

        { //The constructor start
        ++counter; 
    

    it adds one plus per each object created;

        cout << "Employee constructor for " << firstName
             << ' ' << lastName << " called." << endl;
        }
    
        ~Employee() { 
    

    Destructor cout << "~Employee() called for " << firstName << ' ' << lastName << endl;

    Returns the first and last name of each object

            --counter; 
    

    Counter minus one

        }
    
        string getFirstName() const {
            return firstName; 
        }
    
        string getLastName() const {
            return lastName;
        }
    
        static int getCount() {
            return counter;
        }
    private:
        string firstName;
        string lastName;
    
       static int counter = 0; 
    

    Here is where i got the error. But, why?

    };
    

    principal program: 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; 
    

    Here ir call te counter's value from the class

        { 
    

    Start a new scope block

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

    Initialize the e1 object from Employee class

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

    Initialize the e2 object from Employee class

            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";
        } 
    

    end the scope block

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

    What is the problem? I have no idea what's wrong. I have been thinking a lot, but a i do not what is wrong.

    • PMF
      PMF over 10 years
      I don't think that's what he wants, since counter is being modified later.
    • Uchia Itachi
      Uchia Itachi over 10 years
      @PMF: Yeah, you're right!
    • mishelashala
      mishelashala over 10 years
      I want initialize counter and later increment it with the constructor. Then decrement it with the destructor.
    • SwiftMango
      SwiftMango over 10 years
      I don't think the error message can be any clearer.
    • mucaho
      mucaho over 8 years
      @texasbruce The error message only tells you what's wrong, not how to solve the problem.
  • mishelashala
    mishelashala over 10 years
    I did it, but it returns: In function ‘int main()’: error: ‘int Employee::counter’ is private error: within this context
  • PMF
    PMF over 10 years
    @user3053929: Where did you put it? It needs to be outside any function but where the class Employee is known. BTW: Why is your cpp file called employee2.cpp? And including employee2.h?
  • mishelashala
    mishelashala over 10 years
    Because i did another one. But it does not matter. Thank for the info
  • BozanicJosip
    BozanicJosip over 6 years
    if that's sole reason why it's prevented, why const members are allowed? Don't they get initialized in every place where the header is included aswell?
  • PMF
    PMF over 6 years
    @JesusChrist: Not sure. Either it wouldn't matter if the const member got a new memory location every time (in fact existing multiple times) or not at all (because it gets eliminated by the compiler)