得到80语法 - 在参数列表中初始化

时间:2011-10-31 21:30:16

标签: c++ gotw

Gotw 80包含以下示例:

  // Example 1
  //
  #include <string>
  using namespace std;

  class A
  {
  public:
    A( const string& s ) { /* ... */ }
    string f() { return "hello, world"; }
  };

  class B : public A
  {
  public:
    B() : A( s = f() ) {}
  private:
    string s;
  };

  int main()
  {
    B b;
  }

本文将讨论为什么行s = f()不正确 - 由于对象的生命周期和构造顺序。文章指出,当时,编译器没有发现错误。

但是,忽略了初始化和对象生命周期的问题,我没有看到构造函数的参数列表中s = f()如何在语法上合法 - 它似乎试图初始化一个成员参数列表(或可能声明默认值)。任何人都可以解释这种语法试图做什么吗?

2 个答案:

答案 0 :(得分:3)

看起来打算调用f()并将结果分配给B::s。之后,在调用继承的s构造函数时,该赋值的结果(A)将用作实际参数。

它在语法上是有效的。用一些非成员变量和g++ accepts it without issue替换该表达式中的s。您可能会看到类似的语法更常用于普通函数调用而不是构造函数调用。

答案 1 :(得分:1)

从语法上讲它是合法的...当你有一个带有参数的构造函数的基类时,你当然可以将任何表达式作为参数传递:

strut A {
    A(int) {}
};

struct B : A {
    B() : A( any expression that returns an int ) {}
};

问题在于,在评估示例中的表达式时,对象甚至还不是完全构造的A实例,因此代码无效,原因有两个:

  1. 调用非实例A的方法(构造函数尚未启动):f()调用是非法的。
  2. 分配给尚未初始化的成员:s=...是非法的。