C ++:通过类或实例访问const成员变量?

时间:2009-08-06 20:07:38

标签: c++ static const

在C ++中,有没有理由不通过类实例访问静态成员变量?我知道Java对此皱眉,并想知道它是否在C ++中很重要。例如:

class Foo {
  static const int ZERO = 0;
  static const int ONE = 1;
  ...
};


void bar(const Foo& inst) {
   // is this ok?
   int val1 = inst.ZERO;
   // or should I prefer:
   int val2 = Foo::ZERO
   ...
};

我有第二个问题。如果我声明一个静态double,我必须在某处定义它,并且该定义必须重复该类型。为什么必须重复这种类型? 例如:

In a header:
  class Foo {
    static const double d;
  };
In a source file:
  const double Foo::d = 42;

为什么我必须在cpp文件中重复“const double”部分?

6 个答案:

答案 0 :(得分:6)

我希望Foo::ZERO超过inst.ZERO,因为它更清楚地告诉我们发生了什么。但是,在类Foo的方法中,我只使用ZERO

至于奖金问题,const只是完整类型的一部分。

答案 1 :(得分:5)

对于第一个问题,除了风格问题(它显然它是一个类变量并且没有相关对象),Fred Larsen在对问题的评论中提到了前一个问题。请阅读Adam Rosenthal's answer以了解非常为什么要小心这一点。 (如果弗雷德将其作为答案发布,我会对其进行投票,但我不能相信它应该归还的地方。我向亚当投票了。)

至于你的第二个问题:

  

为什么我必须在cpp文件中重复“const double”部分?

您必须首先重复该类型作为实现细节:它是C ++编译器解析声明的方式。这对于局部变量也不是非常理想的,并且C ++ 1x(以前的C ++ 0x)使用auto关键字来避免需要对常规函数变量重复。

所以这个:

vector<string> v;
vector<string>::iterator it = v.begin();

可以成为:

vector<string> v;
auto it = v.begin();

没有明确的理由说明为什么这也不适用于静态,所以在你的情况下thos:

const double Foo::d = 42;

很可能成为这个。

static Foo::d = 42;

关键是要有一些方式将其识别为声明。

注意我说没有清除原因:C ++的语法是一个活生生的传说:非常很难涵盖所有边缘情况。我不认为以上是模棱两可的,但可能是。如果不是,他们可以将其添加到语言中。告诉他们...对于C ++ 2x:/。

答案 2 :(得分:3)

鉴于你将它们声明为静态并使它们成为类常量,我会使用Foo :: Zero将意图传达给随意而不那么随意的代码读者。

我还会替换常量的全部大写名称,即将Foo :: ZERO转换为Foo :: Zero。预处理程序宏的常规约定是将它们全部用大写命名,并且对C ++常量使用类似的命名方案会遇到麻烦,因为预处理程序可能会对您的C ++常量进行调整,最终会得到非常有趣的错误消息。

答案 3 :(得分:1)

我会使用Foo :: ZERO,但那只是我。特别是如果你来自Foo,那会让人感到困惑。

对于第二个问题,您需要为double值创建内存,这在实现单元中发生。

我认为你不需要创建内存的唯一类型是const整数类型。然后,您可以将值放在头文件中。但由于它没有地址,因此除非将定义放在.cpp文件中,否则无法通过引用函数来传递它。 (这似乎是它与gcc一起使用的方式)。

答案 4 :(得分:1)

您在示例中使用哪种形式无关紧要。它们都意味着同样的事情。我更喜欢一般使用类方法,因为你可能并不总是有一个实例方便使用点运算符。

如果你考虑有人写一个模板函数,那么有两个选项是很好的。他们可能用点运算符编写了函数。具有静态类成员的类仍可用于实例化模板,因为支持该语法。

至于你的奖金问题,这就是语言的方式。您始终必须声明完整类型。你应该在一个单独的问题中提出这个问题。

答案 5 :(得分:1)

我亲自使用匿名枚举。尽管最终结果完全相同:)

至于你的问题。我肯定更喜欢Foo :: Zero,因为通过查看它所访问的内容显而易见。 inst.Zero要求你事先弄清楚什么类型的inst。

您必须重复数据类型,因为这就是C ++的工作原理。如果您在头文件中编写以下内容,则采用相同的方式。

extern int foo;

您仍需要提及

int foo

在CPP文件中。正如pukku提到的那样,你声明了一个类型为“const int”的变量。因此,必须在变量的定义中重复“const int”。