相关疑难解决方法(0)

C++ 11允许非静态和非const成员的类内初始化.改变了什么?

在C++ 11之前,我们只能对整数或枚举类型的静态const成员执行类内初始化.Stroustrup在他的C++ FAQ中讨论了这个问题,给出了以下示例:

class Y {
  const int c3 = 7;           // error: not static
  static int c4 = 7;          // error: not const
  static const float c5 = 7;  // error: not integral
};
Run Code Online (Sandbox Code Playgroud)

以下推理:

那么为什么存在这些不方便的限制呢?类通常在头文件中声明,并且头文件通常包含在许多翻译单元中.但是,为避免复杂的链接器规则,C++要求每个对象都有唯一的定义.如果C++允许将需要作为对象存储在内存中的实体的类内定义,则该规则将被破坏.

但是,C++ 11放宽了这些限制,允许非静态成员的类内初始化(§12.6.2/ 8):

在非委托构造函数中,如果给定的非静态数据成员或基类未由mem-initializer-id指定(包括没有mem-initializer-list的情况,因为构造函数没有ctor-initializer)然后,实体不是抽象类(10.4)的虚基类

  • 如果实体是具有大括号或等于初始值的非静态数据成员,则按照8.5中的规定初始化该实体;
  • 否则,如果实体是变体成员(9.5),则不执行初始化;
  • 否则,实体默认初始化(8.5).

第9.4.2节还允许非const静态成员的类内初始化,如果它们用说明constexpr符标记的话.

那么我们在C++ 03中受到限制的原因究竟发生了什么?我们只是简单地接受"复杂的链接器规则"或者是否有其他改变使得这更容易实现?

c++ initialization class class-members c++11

80
推荐指数
3
解决办法
9万
查看次数

在C++中定义静态成员

我试图定义一个这样的公共静态变量:

public :
         static int j=0;        //or any other value too
Run Code Online (Sandbox Code Playgroud)

我在这一行得到了一个编译错误:ISO C++禁止非const静态成员`j'的类内初始化.

  1. 为什么在C++中不允许这样做?

  2. 为什么允许const成员初始化?

  3. 这是否意味着C++中的静态变量没有像C一样用0初始化?

谢谢 !

c++ static

25
推荐指数
4
解决办法
3万
查看次数

为什么需要明确定义静态变量?

在课堂里:

class foo
{
public:
    static int bar; //declaration of static data member
};

int foo::bar = 0; //definition of data member
Run Code Online (Sandbox Code Playgroud)

我们必须明确定义静态变量,否则会产生一个

undefined reference to 'foo::bar'

我的问题是:

为什么我们必须给出静态变量的明确定义?


请注意,这与先前提出的问题重复undefined reference to static variable.这个问题打算问一下静态变量的明确定义背后的原因.

c++ static

25
推荐指数
1
解决办法
2097
查看次数

关于静态常量数据成员的声明和定义的混淆

Scott Meyers 在 Effective Modern C++, Item 30 page 210 中写道,有

无需static const在类中定义完整的数据成员;仅声明就足够了,

那么示例代码是

class Widget {
  public:
    static const std::size_t MinVals = 28; // MinVals' declaration;
    ...
};
...                                        // no defn. for MinVals
std::vector<int> widgetData;
widgetData.reserve(Widget::MinVals);       // use of MinVals
Run Code Online (Sandbox Code Playgroud)

我确信这static const std::size_t MinVals = 28;既是声明是定义,因为它给了一个值MinVals,但评论似乎声称这只是一个声明;第二条评论实际上声称没有定义。代码后面的文字,确实是读

MinVals 缺乏定义。

这证实这static const std::size_t MinVals = 28;不是一个定义,所以我有点困惑。

cppreference对我帮助不大(我的粗斜体):

如果声明static了整型或枚举类型的数据成员(而不是),则可以使用初始化器对其进行初始化,其中每个表达式都是常量表达式,就在类定义中: constvolatile

struct X
{
   const static int …
Run Code Online (Sandbox Code Playgroud)

c++ static variable-declaration language-lawyer

24
推荐指数
1
解决办法
1218
查看次数

为什么需要在类外部初始化非常量静态变量?

我知道非常量静态变量需要在类定义之外进行初始化,但有没有理由呢?

class A {
    static int x = 0 // compile error;
    static int y;
};

int A::y = 0; // fine
Run Code Online (Sandbox Code Playgroud)

c++ static

17
推荐指数
2
解决办法
2412
查看次数

为什么必须在定义之外初始化非const,非int/enum静态数据成员?

我知道只有静态,const和int/enum(pre c ++ 11)的数据成员才能在类声明中初始化."所有其他静态数据成员必须在全局命名空间范围内定义(即在类定义的主体之外),并且只能在这些定义中初始化".

为什么不能在类定义中初始化其他静态数据成员?这是被禁止的具体原因吗?

如果数据成员特定于该类,为什么它们在全局命名空间范围内声明,而不是与其类相关的某些范围?

c++ static header

6
推荐指数
1
解决办法
1699
查看次数

定义constexpr静态数据成员

因此,我知道在C ++中,如果静态成员是const文字类型,则可以在类内部对其进行初始化,如下所示:

class test{
public:
        static constexpr int stc = 1;
private:
        int a = 0;
        int b = 0;
        int c = 0;
};
Run Code Online (Sandbox Code Playgroud)

静态constexpr变量stc可以用在编译器可以直接替换成员值的地方,即

int main () {int array[test::stc];}  
Run Code Online (Sandbox Code Playgroud)

但是,如果在不能由编译器直接替换值的上下文中使用:

int main() { const int &cs = test::stc; } 
Run Code Online (Sandbox Code Playgroud)

然后编译器(c)生成一个错误

c++ -std=c++11 -pedantic    t.cpp   -o t
Undefined symbols for architecture x86_64:
  "test::stc", referenced from:
      _main in t-a8ee2a.o
ld: symbol(s) not found for architecture x86_64
Run Code Online (Sandbox Code Playgroud)

除非静态成员是在类外部定义的,例如:

constexpr int test::stc;

为什么会这样呢?

c++ static class constexpr c++11

5
推荐指数
1
解决办法
1050
查看次数