静态const变量在子类中不是常量

hea*_*vyd 2 c++ inheritance visual-c++-2008

我正在使用Visual Studio 2008,并有两个类Parent和Child.Parent在头文件中声明了一些静态const变量,然后在cpp文件中定义.当我尝试在子类的switch语句中使用define作为案例时,我得到错误: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;
  }
}
Run Code Online (Sandbox Code Playgroud)

我也试过Parent::B直接指定,但没有解决问题.除非从父类继承变量,否则表达式在所有情况下都是常量是否有某些原因?

Jam*_*lis 7

如果是,则只能static const在常量表达式中使用整数类型的成员变量

  • 它用一个常量表达式初始化
  • 该常量表达式在使用时是可见的.

在你的中switch,值Parent::A是可见的,因为它的初始值设定项在Parent.h头文件中.同样的道理Child::C.值Child::D是可见的,因为它的初始化程序在Child.cpp中较早出现.

但是,值Parent::B不可见:C++源文件是单独编译的,因此在编译Child.cpp时,编译器知道它Parent::B是一个static const整型变量成员变量,但它不知道它的值是什么.因此,它不能用于Child.cpp中的常量表达式.


请注意,如果您曾Parent::A用作对象(例如&Parent::A),您仍然需要B在Parent.cpp中定义,使用const unsigned long Parent::A;没有初始化程序,因为您将初始化程序放在类定义中.