编译器自动确定构造函数初始化列表

Automatic determination of the constructor initialization list by the compiler?

本文关键字:构造函数 初始化 列表 编译器      更新时间:2023-10-16

我在问自己(找不到答案),如果现代c++编译器可以检查到构造函数的主体,看看他们是否可以推断初始化列表,而不是让开发人员指定它?

作为一个例子,考虑下面的代码:

MyClass::MyClass (Obj o)
{
    _o = o;
}

编译器能自动翻译成:

MyClass::MyClass (Obj o) : _o(o)
{}

谢谢

这是不可能的,因为它在一般情况下完全改变了程序的语义。一些例子:

// Order of evaluation:
struct Foo {
   int a, b;
   Foo() : b(a) { a = 1; }    // differs from Foo() : a(1), b(a) {}
};
// Legality of the operation:
struct X { explicit X(int x); };
struct Foo {
    X x;
    Foo() { x = 5; }              // Ill formed, while Foo() : x(5) is well formed
};
// Different effects even if allowed
struct X {
   X(int)            { std::cout << "intn";        }
   X()               { std::cout << "defaultn";    }
   X& operator=(int) { std::cout << "assignmentn"; }
};
struct Foo {
   X x;
   Foo() { x = 5; }          // prints: defaultnassignmentn
   // Where Foo() : x(5) {}  // prints: intn
};

在语言级别,这两种操作是完全不同的,不能转换。话虽如此,如果它们确实相等,那么优化器可能能够为它们生成完全相同的代码。

不,因为语义不同。下面的语句直接初始化来自o的成员_o:

MyClass::MyClass (Obj o) : _o(o)
{}

另一方面,下面默认初始化_o,然后将o的值赋给它:

MyClass::MyClass (Obj o)
{
    _o = o;
}

在某些情况下,实际上可能没有有效的区别,例如Obj实际上是int。在没有有效区别的情况下,也许编译器会为两种情况生成相同的代码,但也可能不是。

它们正在检查(如果需要创建带参数的成员变量)

例如:

struct A {
  A( int ) {}
};
struct B {
  B(){ a = A(3); }
  A a;
};

将失败并出现错误。

另一方面,有些类型不需要初始化形参。例如:
struct A
{
    A(){
        v = 3;
    }
    int v;
};

标准不要求编译器发出警告,但有些编译器可以这样做(gcc有- weffc++标志)。

此外,还有静态代码分析工具来警告此类"错误"。