web-dev-qa-db-ja.com

エラー:ISO C ++は、非const静的メンバーのクラス内初期化を禁止します

これはヘッダーファイルです: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; 

作成されたオブジェクトごとに1プラスを追加します。

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

    ~Employee() { 

デストラクタcout << "〜Employee()が呼び出された" << firstName << '' << lastName << endl;

各オブジェクトの姓と名を返します

        --counter; 

カウンターマイナス1

    }

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

Employeeクラスからe1オブジェクトを初期化します

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

Employeeクラスからe2オブジェクトを初期化します

        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

何が問題ですか?何が悪いのか分かりません。私はずっと考えてきましたが、私は何が悪いのではありません。

15
mishelashala

静的メンバーcounterの-​​初期化をヘッダーファイルに含めることはできません。

ヘッダーファイルの行を

static int counter;

そして、employee.cppに次の行を追加します。

int Employee::counter = 0;

その理由は、ヘッダーファイルにそのような初期化を設定すると、ヘッダーが含まれるすべての場所で初期化コードが複製されるためです。

50
PMF

aimilar SO answer によれば、現在の実装に特に適した別のアプローチがあります(ヘッダーのみのライブラリ):

// 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 負でない従業員数を表す場合、および 末尾復帰構文 関数の場合。

付随するテスト( 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;
}
1
mucaho