在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
...
};
我有一个额外的第二个问题。 如果我声明静态双,我必须从某个地方把它定义和定义有重复的类型。 为什么类型必须重复? 例如:
In a header:
class Foo {
static const double d;
};
In a source file:
const double Foo::d = 42;
我为什么要重复我的cpp文件中的“常量双”的一部分?
对于第一个问题,除了款式的事(这使得很明显这是一个类变量,没有关联的对象),弗雷德·拉森,在注释中的问题,提到了前面的问题。 阅读亚当·罗森塔尔的答案为什么你要小心这个理由很充分。 (我赞成票弗雷德如果他张贴作为答案,但我不能这么信贷,这是因为我做了赞成票亚当。)
关于你提到的第二个问题:
我为什么要重复我的cpp文件中的“常量双”的一部分?
你必须重复的类型主要是作为一个实现细节:这是C ++编译器如何解析的声明。 这不是严格理想的局部变量要么和C ++ 1X(以前的C ++ 0x)利用了的auto
关键字,以避免需要来获得重复性定期函数变量。
所以这:
vector<string> v;
vector<string>::iterator it = v.begin();
能成为这样的:
vector<string> v;
auto it = v.begin();
有没有明确的理由,为什么这可能不是静态的工作一样,所以你的情况茨艾伦:
const double Foo::d = 42;
很可能成为这一点。
static Foo::d = 42;
最关键的是要有确定这是一个宣言的一些方法。
请注意我说没有明确的理由:C ++的语法是一个活着的传奇:它是非常难以涵盖其所有的边缘情况。 我不认为上述是模糊的,但它可能是。 如果不是他们可以添加到语言。 告诉他们吧......对C ++ 2倍:/。
我宁愿Foo::ZERO
在inst.ZERO
,因为它更清楚地告诉是怎么回事。 然而,在类的方法Foo
,我只想用ZERO
。
至于奖金问题, const
仅仅是完整的类型的一部分。
既然你都声明为静态的,让他们类的常量,我会用美孚::零的意图传达给你的代码的随意和不那么普通读者。
我也将取代常数的全部大写的名字,也就是把富:: ZERO成富::零。 对于预处理宏通常惯例是他们的名字全部大写,并使用你的C ++常数相似的命名方案,自找麻烦,因为预处理器可能只是在你的C ++常量BLAT和你结束了非常有趣的错误消息。
我会用美孚:: ZERO,但是,这只是我的。 特别是如果你从富,它获取混乱派生。
关于第二个问题,你需要为双价值创造记忆,并在实施单位出现这种情况。
我想,你不需要为创建存储的唯一类型是一个const整型。 然后,您可以把值在头文件。 但是,因为它没有地址,您将无法按引用传递它的功能,除非你把一个定义在.cpp文件。 (这似乎是它的工作原理与海湾合作委员会的方式)。
不要紧,形成你在你的例子中使用。 他们都意味着同样的事情。 我宁愿使用类的方式一般是因为你可能并不总是有得心应手的实例即可使用点运算符上。
如果你认为有人写一个模板函数它是好的,有两种选择。 他们可能已经编写用点操作的功能。 您与类的静态成员类仍可使用,因为语法支持实例化的模板。
至于你的奖金问题,这仅仅是语言的方式。 你总是要申报的全部类型。 你可能要问,在一个单独的问题。
个人而言,我会使用匿名枚举。 最终的结果是完全一样的,虽然:)
至于你的问题。 我一定会研究一下,你正在访问什么喜欢的Foo ::为零,因为其明显的。 inst.Zero需要你找出什么类型的研究所是前手。
你必须重复数据类型,因为这就是C ++如何工作的。 以同样的方式,如果你写在头文件如下。
extern int foo;
您仍然需要提
int foo
在CPP文件。 正如pukku提到您声明型“const int的”的变量。 因此,“const int的”必须在变量的定义中重复。