宣布正常类和类模板的静态数据成员(Declaring static data members of

2019-08-17 15:47发布

我读的源文件中定义静态数据成员,是因为如果他们在头文件和多个源文件包含文件级的定义的头会得到输出多次。 我明白为什么这将是静态常量数据成员的问题,但为什么这是静态数据成员的问题吗?

我不太确定我完全理解为什么那里,如果定义写在头文件是一个问题...

Answer 1:

我想你混淆了两个方面: static数据成员和全局变量市场上赢得的static

后者具有内部链接 ,这意味着,如果你把自己定义在多个翻译单位的头文件#include每个转换单元将接收这些变量的专用副本

标记为全局变量const都默认内部链接,这样你就不会需要指定static明确那些。 因此,链接器不会抱怨全球的多个定义const变量或全球非的const变量标记为static ,而它将会在其他情况下,抱怨(因为这些变量将有外部链接)。

关于static数据成员,这是段的C ++标准11 9.4.2说/ 5:

static命名空间范围的一类的数据成员具有外部连接 (3.5)。 局部类不得有static数据成员。

这意味着,如果你把自己定义在一个头文件中#include由多个翻译单元d,你最终会在相应的目标文件(酷似非同一符号的多个定义const全局变量),不管他们const企业资质是。 在这种情况下,你的程序将违反一个定义规则

此外, 这个Q&A在计算器上可能会给你的主题更清楚的了解。



Answer 2:

对于变量的多个定义问题是在语言的定义主要有两个不足之处。

如下图所示,你可以很容易地解决它。 没有技术的原因没有直接的支持。 它与人们对委员会的选择,使其优先足够高的需求不被该功能做。

首先,为什么在一般的多个定义是一个问题。 由于C ++没有支持单独编译的模块(缺陷#1),程序员必须通过使用文本预处理等,以仿真功能,然后很容易在不经意间引入相同的名称,这将很可能是错误的两个或两个以上的定义。

对于此功能通过解决inline关键字和财产。 一个独立的功能仅可以显式inline ,而一个成员函数可以是隐式地inline通过在类定义被定义。 无论哪种方式,如果一个功能是inline话,就可以在多个翻译单位定义,它必须在每个翻译单元使用它的定义,这些定义必须是等价的。

在头文件中定义主要是溶液允许类。

需要没有这样的语言功能,支持数据,在头文件中定义的变量,所以它只是不存在:你不能有inline变量。 这是语言的缺陷#2。

不过,你能获得的效果 inline变量通过一个特殊的豁免static类模板的数据成员。 究其原因,豁免该类模板一般在头文件中被完全定义(除非该模板仅在翻译单元内部使用)等一类模板能够有static数据成员,这是必要的无论是从一般规则的豁免,或一些特殊的支持。 该委员会选择了豁免,来自该规则的路线。

template< class Dummy >
struct math_
{
    static double const pi;
};

template< class Dummy >
double const math_<Dummy>::pi = 3.14;

typedef math_<void> math;

上面已经被称为模板常量特技 。 据我知道我是谁,一旦推出它的[comp.lang.c ++]新闻组中一个,所以我不能给别人给予信贷。 我也贴了几次,在这里左右。

无论如何,这意味着每一个C ++编译器和连接器内部支持,必须支持所需的机械inline数据,然而语言不具有该功能。

然而,在第三手,C ++ 11 constexpr ,在那里你可以写上面刚刚

struct math
{
    static double constexpr pi = 3.14;
};

嗯,是有区别的,你不能把C ++ 11的地址math::pi ,但是这是一个非常小的限制。



文章来源: Declaring static data members of normal class and class template