web-dev-qa-db-ja.com

クラス内でconstメンバー変数を初期化する方法

#include <iostream>

using namespace std;
class T1
{
  const int t = 100;
  public:

  T1()
  {

    cout << "T1 constructor: " << t << endl;
  }
};

Constメンバー変数tを100で初期化しようとしていますが、次のエラーが発生します。

test.cpp:21: error: ISO C++ forbids initialization of member ‘t’
test.cpp:21: error: making ‘t’ static

const値を初期化するにはどうすればいいですか?

92
Chaitanya

const変数は、変数が変更可能かどうかを指定します。割り当てられた定数値は、変数が参照されるたびに使用されます。割り当てられた値はプログラムの実行中に変更することはできません。

Bjarne Stroustrupの 説明 簡単に要約すると:

クラスは通常ヘッダーファイルで宣言され、ヘッダーファイルは通常多くの翻訳単位に含まれます。ただし、複雑なリンカ規則を避けるために、C++ではすべてのオブジェクトに一意の定義が必要です。 C++がオブジェクトとしてメモリに格納する必要があるエンティティのクラス内定義を許可した場合、その規則は破られるでしょう。

const変数はクラス内で宣言する必要がありますが、その中で定義することはできません。クラスの外でconst変数を定義する必要があります。

T1() : t( 100 ){}

ここでの代入t = 100は初期化子リストの中で、クラスの初期化が起こるずっと前に起こります。

104
Dinkar Thakur

まあ、あなたはそれをstaticにすることができます:

static const int t = 100;

あるいは、メンバー初期化子を使うこともできます。

T1() : t(100)
{
    // Other constructor stuff here
}
45
Fred Larson

クラス内でconstメンバを初期化する方法はいくつかあります。

Constメンバの定義は一般的に、変数の初期化も必要です。

1)クラス内で、constを初期化したい場合、構文は次のようになります。

static const int a = 10; //at declaration

2)第二の方法はすることができます

class A
{
  static const int a; //declaration
};

const int A::a = 10; //defining the static member outside the class

3)宣言時に初期化したくない場合は、もう1つの方法はコンストラクタを使用することです。変数は初期化リストで(コンストラクタの本体ではなく)初期化する必要があります。このようにする必要があります

class A
{
  const int b;
  A(int c) : b(c) {} //const member initialized in initialization list
};
28
ravs2627
  1. C++ 11をサポートするようにコンパイラをアップグレードすれば、コードは完全に機能します。

  2. コンストラクタで初期化リストを使用してください。

    T1() : t( 100 )
    {
    }
    
12
borisbn

constデータメンバをクラスstaticにしたくない場合は、クラスのコンストラクタを使用してconstデータメンバを初期化できます。例えば:

class Example{
      const int x;
    public:
      Example(int n);
};

Example::Example(int n):x(n){
}

クラスに複数のconstデータメンバがある場合は、次の構文を使ってメンバを初期化できます。

Example::Example(int n, int z):x(n),someOtherConstVariable(z){}
9
GANESH B K

別の解決策は

class T1
{
    enum
    {
        t = 100
    };

    public:
    T1();
};

そのため、tは100に初期化され、変更することはできず、非公開です。

5
Musky

メンバーが配列の場合、通常の値よりも少し複雑になります。

class C
{
    static const int ARRAY[10];
 public:
    C() {}
};
const unsigned int C::ARRAY[10] = {0,1,2,3,4,5,6,7,8,9};

または

int* a = new int[N];
// fill a

class C {
  const std::vector<int> v;
public:
  C():v(a, a+N) {}
};
3
Viet Anh Do

もう一つの可能​​な方法は名前空間です:

#include <iostream>

namespace mySpace {
   static const int T = 100; 
}

using namespace std;

class T1
{
   public:
   T1()
   {
       cout << "T1 constructor: " << mySpace::T << endl;
   }
};

不利な点は、他のクラスがヘッダファイルを含んでいる場合、他のクラスもその定数を使用できることです。

2
Baran

このクラスメンバー変数の初期化を可能にするためにstaticを追加できます。

static const int i = 100;

ただし、そのクラスからインスタンス化されたすべてのオブジェクトは、インスタンス化されたオブジェクトのスコープメモリ外の内部メモリに格納されている同じ静的変数を共有するため、内部クラス宣言を使用することは必ずしもお勧めできません。

0
dhokar.w

これは正しい方法です。あなたはこのコードを試すことができます。

#include <iostream>

using namespace std;

class T1 {
    const int t;

    public:
        T1():t(100) {
            cout << "T1 constructor: " << t << endl;
        }
};

int main() {
    T1 obj;
    return 0;
}

C++10 Compiler or belowを使用している場合は、宣言時にconsメンバーを初期化することはできません。そのため、ここではconstデータメンバを初期化するためのコンストラクタを作成する必要があります。また、メモリを即座に取得するには、イニシャライザリストT1():t(100)を使用する必要があります。

0
Gambler Aziz