1

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()构造函数的参数列表在语法上如何合法 - 它似乎试图初始化参数列表中的成员(或者可能声明默认值价值)。谁能解释这个语法试图做什么?

4

2 回答 2

3

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

它在语法上是有效的。s用一些非成员变量替换该表达式, g++ 毫无问题地接受它。您可能会看到类似的语法更常用于普通函数调用而不是构造函数调用。

于 2011-10-31T21:33:05.423 回答
1

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

strut A {
    A(int) {}
};

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

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

  1. 调用A非实例的方法(构造函数尚未启动):f()调用是非法的。
  2. 分配给尚未初始化的成员:s=...是非法的。
于 2011-10-31T21:47:55.173 回答