初始化列表与类型转换(C++)

初始化列表和构造函数体在C++中都是用于给类的成员变量赋初值

区别:初始化列表是给每个成员变量定义初始化的地方,即使有成员变量没有给它显式在初始化列表初始化,它也会走初始化列表

初始化时机

  • 初始化列表:在对象创建时,成员变量通过初始化列表被直接初始化,这发生在构造函数体执行之前。

  • 构造函数体内赋值:成员变量首先被默认初始化,然后在构造函数体内通过赋值语句进行赋值。

性能差异

  • 初始化列表:通常更高效,因为它避免了成员变量的默认构造和后续的赋值操作,直接调用成员变量的构造函数进行初始化。

  • 构造函数体内赋值:可能导致额外的开销,特别是对于类类型成员,会先调用默认构造函数,然后再进行赋值,造成不必要的构造和析构。

适用性

  • 初始化列表:适用于所有成员变量,特别是必须初始化的const成员、引用成员,以及没有默认构造函数的类类型成员。

  • 构造函数体内赋值:不适用于const成员和引用成员,因为这些成员必须在初始化时赋值,且之后不能改变。

初始化顺序

  • 初始化列表:成员变量的初始化顺序按照它们在类中声明的顺序进行,而不是初始化列表中的顺序。

  • 构造函数体内赋值:赋值顺序按照代码编写的顺序进行

初始化列表的语法格式是以一个冒号开头,以逗号进行分割的数据成员列表,每个成员变量后面跟着一个放在括号里面的初始值或者表达式

class MyClass
{
public:
	MyClass(int n) :_a(n),_b(0){};
private:
	int _a;
	int _b;
};
int main()
{
	MyClass a(5);
	return 0;
}
初始化列表的作用
  • 提高效率:初始化列表在对象创建时直接为成员变量赋值,避免了先调用默认构造函数再赋值的过程,从而提高了效率。

  • 初始化特殊成员常量(const)和引用(&)类型的成员变量必须在声明时初始化,且之后不能修改,因此必须使用初始化列表进行初始化

  • 初始化成员对象:如果类中包含其他类类型的成员对象,且该对象没有默认构造函数,则需要通过初始化列表来初始化这些成员对象。

注意事项
  • 成员变量的初始化顺序按照它们在类中声明的顺序进行,而不是初始化列表中的顺序。

  • 初始化列表中的表达式仅用于初始化,不能调用函数或执行复杂操作

c++11还支持:在声明的时候给值,这个值相当于缺省值,如果没有在初始化列表进行显式初始化,该对象就会被初始化成该缺省值

初始化列表与类型转换(C++)_第1张图片

类型转换

C++允许内置类型隐式转换成类类型,但需要有该内置类型作为参数的构造函数

初始化列表与类型转换(C++)_第2张图片

1是内置类型,它首先构造了一个MyClass类型的临时对象,然后拷贝构造给了b

编译器会将构造+拷贝构造 优化为直接构造,所以实际操作过程中只会调用一次直接构造,不会调用拷贝构造

它是有意义的

假设栈里面要push的是一个A类型的对象,首先要构造这个对象(有名对象)然后再去传

但是有了隐式类型转换,传参时就可以直接传该对象的 构造函数的 参数类型对象,便利了不少

但要注意的是,如果此时接收的形参是引用类型,就要加上const,因为临时对象具有常性

加explicit关键字,将不会发生类型转换

在构造函数前加上 explict,该构造函数就不会进行隐式类型转换

多参数也能进行隐式类型转换,但是要加花括号

初始化列表与类型转换(C++)_第3张图片

不能直接使用圆括号,那是逗号表达式

初始化列表与类型转换(C++)_第4张图片

类类型 到 类类型 有构造支持也可以进行类型转换

你可能感兴趣的:(c++,开发语言)