类成员初始化顺序,C++; P>所有的古今C++书籍和专家都声明通过声明顺序初始化类成员。但两者都不能解释如果我不这么做呢?? 我不是在说有const类型或smth成员的类。。只是简单的类

类成员初始化顺序,C++; P>所有的古今C++书籍和专家都声明通过声明顺序初始化类成员。但两者都不能解释如果我不这么做呢?? 我不是在说有const类型或smth成员的类。。只是简单的类,c++,class,constructor,initialization,C++,Class,Constructor,Initialization,考虑以下示例: class A { int n; std::vector<double> VD; char c; public: A(): VD(std::vector<double>(3)), c('a'), n(44) { } }; A类 { int n; std::矢量VD; 字符c; 公众: A(): VD(std::vector(3)), c(“a”), n(44) { } }; 书

考虑以下示例:

class A
{
  int n;
  std::vector<double> VD;
  char c;
public:
  A():
      VD(std::vector<double>(3)),
      c('a'),
      n(44)
      {
      }
};
A类
{
int n;
std::矢量VD;
字符c;
公众:
A():
VD(std::vector(3)),
c(“a”),
n(44)
{
}
};

书面代码与声明顺序相同的代码有什么区别?

您不能更改初始化顺序-这是成员在类中出现的顺序-初始化列表中的顺序不重要,尽管编译器可能会在两个顺序不匹配时发出警告。

您不能更改初始化顺序-这是成员在类中出现的顺序-初始化列表中的顺序不重要,但编译器可能会在两个顺序不匹配时发出警告。

生成的程序集中应该绝对没有差异,尽管“好像”规则可能会妨碍你

至少在概念上,
n
是在
c
之前初始化的


参考资料:

生成的程序集应该绝对没有差异,尽管“好像”规则可能会造成阻碍

至少在概念上,
n
是在
c
之前初始化的

参考:

书面代码和声明顺序相同的代码有什么区别

如果成员不依赖于彼此的初始化顺序,则没有任何区别。但如果他们这样做了,那么成员初始化列表可能在撒谎

当许多程序员认为自己的构造函数写得正确时,他们会被这一点所困扰,但事实上,他们的手上有未定义的行为

考虑这个简单的例子:

struct foo {
  int _a;
  int _b;
  foo(int b) : _b(b), _a(2 * _b) {}
};
在上面的例子中,
\u a
是什么?如果您回答的不是“行为未定义,因为使用了
\u b
”,那么您就错了

书面代码和声明顺序相同的代码有什么区别

如果成员不依赖于彼此的初始化顺序,则没有任何区别。但如果他们这样做了,那么成员初始化列表可能在撒谎

当许多程序员认为自己的构造函数写得正确时,他们会被这一点所困扰,但事实上,他们的手上有未定义的行为

考虑这个简单的例子:

struct foo {
  int _a;
  int _b;
  foo(int b) : _b(b), _a(2 * _b) {}
};
在上面的例子中,
\u a
是什么?如果您回答的不是“行为未定义,因为使用了
\u b
”,那么您就错了

但这两个都不能解释如果我不这么做怎么办

程序员无法控制它:您在初始化列表中列出成员的顺序对初始化的实际顺序没有影响。编译器忽略列表中项目的顺序,并对表达式重新排序以匹配声明顺序

下面是一个简短的例子来说明这一点:

struct Foo {
    Foo(const char *s) { cout << "Init " << s << endl; }
};
struct Bar {
    Foo a;
    Foo b;
    Foo c;
    Bar() : c("c"), b("b"), a("a") {
    }
};
即使初始化以相反的顺序列出项目

但这两个都不能解释如果我不这么做怎么办

程序员无法控制它:您在初始化列表中列出成员的顺序对初始化的实际顺序没有影响。编译器忽略列表中项目的顺序,并对表达式重新排序以匹配声明顺序

下面是一个简短的例子来说明这一点:

struct Foo {
    Foo(const char *s) { cout << "Init " << s << endl; }
};
struct Bar {
    Foo a;
    Foo b;
    Foo c;
    Bar() : c("c"), b("b"), a("a") {
    }
};
即使初始化以相反的顺序列出项目


我认为有两个理由可以正确订购

  • 声明的顺序与声明的顺序相同,使代码更具可读性,特别是当您希望添加或删除更多变量时
  • 它们的声明顺序表示它们在内存中的顺序。初始化变量时,您有更多的局部性

  • 我认为有两个理由可以合理订购

  • 声明的顺序与声明的顺序相同,使代码更具可读性,特别是当您希望添加或删除更多变量时
  • 它们的声明顺序表示它们在内存中的顺序。初始化变量时,您有更多的局部性

  • 这取决于成员的使用方式。如果存在依赖关系,则必须遵循顺序

    考虑下面的例子

        class x{
             size_t n;
             char * ch; // the size of dynamic char array depends on n
         }
    
    在这里,以不同的顺序初始化将导致未定义的行为


    除此之外,可读性和一致性当然与编码指南POV有关。

    这取决于成员的使用方式。如果存在依赖关系,则必须遵循顺序

    考虑下面的例子

        class x{
             size_t n;
             char * ch; // the size of dynamic char array depends on n
         }
    
    在这里,以不同的顺序初始化将导致未定义的行为


    除了这个原因,当然可读性和一致性在编码指南POV中很重要。

    On(2)如果成员是
    私有的,则不一定如此,尽管我不能绝对肯定这一点。希望@StoryTeller这样的专业人士能证实这一点。@Bathsheba:只有当存在混合可见性时,才可能发生重新排序。具有相同可访问性的所有成员都按声明的顺序排列。但是对于不同可访问性的成员并不能保证。@StoryTeller:如果作者在对利润评论的投票中获得声誉就好了。@Bathsheba-我们因此获得了“权威”徽章。对我来说已经足够好了:POn(2)如果成员是
    私有的
    ,则不一定是,尽管我不能绝对肯定这一点。希望@StoryTeller这样的专业人士能证实这一点。@Bathsheba:只有当存在混合可见性时,才可能发生重新排序。具有相同可访问性的所有成员都按声明的顺序排列。“但是,对于不同可访问性的成员来说,这并不能保证。”故事讲述者:如果作者在利润上升投票中获得声誉就好了