2

Visual Studio 2008を使用していて、親と子の2つのクラスがあります。親はヘッダーでいくつかの静的const変数を宣言し、それらはcppファイルで定義されます。子クラスのswitchステートメントでdefinesascaseを使用しようとすると、次のエラーが発生します。C2051:case式が定数ではありません。だから私はいくつかのテストをしました、そして私が見ている振る舞いは幾分一貫性がありません。

// Parent.h
class Parent
{
public:
    Parent();
    ~Parent(void) { }

  static const unsigned long A = 1;
  static const unsigned long B;
};


// Parent.cpp
#include "Parent.h"

const unsigned long Parent::B = 2;

Parent::Parent()
{
  // Everything works fine here
  unsigned long l;
  switch(l)
  {
  case A:
    break;
  case B:
    break;
  default:
    break;
  }
}

// Child.h
#pragma once
#include "Parent.h"

class Child :
  public Parent
{
public:
  Child(void);
  virtual ~Child(void) { }

  static const int C = 3;
  static const int D;
};

// Child.cpp
#include "Child.h"

const int Child::D = 4;

Child::Child(void)
{
  unsigned long l;
  switch(l)
  {
  case A:
    break;
  case B:  // C2051: case expression not constant
    break;
  case C:
    break;
  case D:
    break;
  default:
    break;
  }
}

また、直接指定してみましParent::Bたが、問題は解決しません。変数が親クラスから継承されている場合を除いて、すべての場合に式が一定である理由はありますか?

4

3 に答える 3

7

static const次の場合にのみ、定数式で整数型のメンバー変数を使用できます。

  • 定数式で初期化され、
  • その定数式は、使用時に表示されます。

では、初期化子が Parent.h ヘッダー ファイルにあるためswitch、 の値が表示されます。Parent::Aについても同様ですChild::C。の値Child::Dが表示されるのは、その初期化子が Child.cpp で前に発生するためです。

ただし、の値Parent::Bは表示されません。C++ ソース ファイルは個別にコンパイルされるため、Child.cpp をコンパイルするとき、コンパイラはそれParent::Bstatic const整数型のメンバー変数であることを認識しますが、その値が何であるかは認識しません。したがって、Child.cpp の定数式では使用できません。


をオブジェクトとして使用Parent::Aする場合 (例: )、クラス定義に初期化子を配置するため、初期化子なしで を使用して Parent.cpp で&Parent::A定義する必要があることに注意してください。Bconst unsigned long Parent::A;

于 2011-03-24T15:58:05.337 に答える
0

その理由は、コンパイラーにとっては定数ではないためです。これは、コンパイル時にはステートメントstatic constをコンパイルするために必要な値がまだないためです。case

この値は、後で がリンクされたときにリンク時に追加されparent.oますchild.o(プラグインまたは共有ライブラリを使用すると、リンク時間は実行時と同じくらい遅くなる可能性があることに注意してください)。

于 2011-03-24T16:14:22.887 に答える
0

Visual Studio では、クラス宣言の外側で const を宣言することを回避できることに驚いています。この線

static const unsigned long B;

親クラス内では許可しないでください。GNU g++ コンパイラを使用する Mac で例を試したところ、次のエラーが発生しました。

error: declaration of 'const long unsigned int Parent::B' outside of class is not definition

あるクラスでは機能するのに、他のクラスでは機能しない理由について。私の推測: child.cpp ファイル内で、コンパイラは D が実際に const として宣言されていることを確認しましたが、B がどのように定義 (または再定義) されたかについては知りません。これを機能させるには、すべての定数宣言を .cpp ファイルではなく .h ファイル内のクラスに移動する必要があります。

于 2011-03-24T16:12:47.867 に答える