编译器自动确定构造函数初始化列表
Automatic determination of the constructor initialization list by the compiler?
我在问自己(找不到答案),如果现代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++标志)。
此外,还有静态代码分析工具来警告此类"错误"。
相关文章:
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 如何在 C++ 中使用它的构造函数初始化 unique_ptrs 的 2D 向量?
- 在C++中使用默认构造函数初始化对象的不同方法
- 使用默认构造函数初始化对象的不同方法
- 我们可以用参数化构造函数初始化结构的数组吗?
- 有没有办法使用该类的构造函数初始化另一个类的私有部分内的对象数组?
- 类内初始化与构造函数初始化列表的顺序
- 通过 C++ 中的重载构造函数初始化未知类型的变量
- 使用复制构造函数初始化 new[]
- 如何从子类的构造函数初始化父类的私有成员
- 在构造函数初始化列表中使用 std::variant
- 使用构造函数初始化结构还是在之后设置其值更好?
- C++ 没有匹配的构造函数初始化 []
- 我正在使用dev c ++,但收到错误(C++98'array'必须由构造函数初始化)
- 使用所述填充构造函数初始化向量中的向量
- 如何同时创建一个具有两个或多个构造函数初始化的对象
- 在 new 关键字中,由默认构造函数初始化的类中的元素是否也使用 new 关键字在C++?
- 这是使用构造函数初始化数组对象的最佳方法吗?
- 内置类型的构造函数初始化
- 构造函数初始化和对象损坏