初始化列表中的序列点警告

时间:2012-04-24 22:41:57

标签: c++ initializer-list sequence-points

我有一个Parent类,它接受两个引用可能实际上也可能不实际引用同一个东西。在这种情况下,当它们相同时,我在Child类的初始化列表中得到一个序列点警告:

class A
{
  public:
    A(int) {}
  private:
    A() {}
};

class Parent
{
  public:
    Parent(A&, A&) {}
};

class Child : public Parent
{
  public:
    Child() :
      Parent(
          *(_A = new A(0)),
          *(_A)) //Warning on this line
  {
  }

  private:
    A *_A;
};

int main(int argc, char** argv)
{
  return 0;
}

我猜这是因为在分配内存后不能保证在该行上取消引用。无论如何,我的问题是,在没有对父母或A进行更改的情况下,是否存在此问题?

1 个答案:

答案 0 :(得分:4)

你是对的,不能保证调用父构造函数的两个参数的顺序(它们之间没有序列点),因此编译器可以在评估{{1}之前合法地评估*(_A) }}

您是否需要动态分配*(_A = new A(0))?如果没有,你可以这样做:

A

有一点需要注意,虽然获取成员的地址或对其进行引用是有效的,但使用class Child : public Parent { public: Child() : Parent( _a, _a ), _a(0) {} private: A _a; // _A is reserved for the implementation (compiler + library) }; 成员之前引用或指针是未定义的行为已初始化,只有在_a构造函数完成后才会发生。也就是说,只要Parent的构造函数只存储引用但不使用对象就是安全的(沿着刀片的边缘骑行,但没有出血)。

如果Parent构造函数使用引用而不是存储它,则可以更改Parent类以接收指向已构造的Child对象的指针:

A