如果现代C ++编译器可以检查构造函数的主体以查看它们是否可以推断初始化列表,而不是让开发人员指定它,我问自己(并且无法找到答案)? / p>
例如,请考虑以下代码:
MyClass::MyClass (Obj o)
{
_o = o;
}
编译器可以自动将其转换为:
MyClass::MyClass (Obj o) : _o(o)
{}
由于
答案 0 :(得分:1)
不,因为语义不同。以下内容直接初始化_o
成员o
:
MyClass::MyClass (Obj o) : _o(o)
{}
另一方面,以下默认值初始化_o
,然后为其指定o
的值:
MyClass::MyClass (Obj o)
{
_o = o;
}
在某些情况下,确实可能没有有效差异,例如Obj
实际上是int
。在没有有效差异的情况下,编译器可能会为这两种情况生成相同的代码,但是再次,也许不会。取决于优化器的巧妙程度。
答案 1 :(得分:1)
这是不可能的,因为它在一般情况下完全改变了程序的语义。一些例子:
// 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 << "int\n"; }
X() { std::cout << "default\n"; }
X& operator=(int) { std::cout << "assignment\n"; }
};
struct Foo {
X x;
Foo() { x = 5; } // prints: default\nassignment\n
// Where Foo() : x(5) {} // prints: int\n
};
在语言层面,两个操作完全不同,无法转换。话虽这么说,如果它们真正等效,优化器可能能够为两者生成完全相同的代码。
答案 2 :(得分:0)
他们正在检查(如果需要使用参数创建成员变量)。
例如,这个:
struct A {
A( int ) {}
};
struct B {
B(){ a = A(3); }
A a;
};
将失败并出现错误。
另一方面,某些类型不需要初始化参数。例如:
struct A
{
A(){
v = 3;
}
int v;
};
标准不要求编译器发出警告,但有些编译器能够执行此操作(gcc has -Weffc++ flag)。
此外,还有静态代码分析工具来警告这种“错误”。