Un artículo para comprender la lista de inicialización del constructor de C++

introducción del problema

Lea el código a continuación:

class Time
{
    
    
public:
	Time(int hour, int min, int sec)
	{
    
    
		_hour = hour;
		_min = min;
		_sec = sec;
	}
private:
	int _hour;
	int _min;
	int _sec;
};

Después de crear una instancia del objeto, el objeto llama automáticamente al constructor para inicializar su propio valor y completar el trabajo de inicialización.Pero no podemos llamarlo inicialización de variables miembro.Porque la inicialización solo se puede inicializar una vez, pero la "inicialización" funciona en el cuerpo de la función, para ser precisos, se puede asignar varias veces, por lo que es parcial considerar la asignación del cuerpo de la función como inicialización.
De ahí la introducción de la lista de inicializadores.

1 lista de inicialización

Sintaxis: comienza con dos puntos, seguido de una lista de miembros de datos separados por comas, cada "variable miembro" seguida de un valor o expresión inicial entre paréntesis.

El formato específico es el siguiente:

class Time
{
    
    
public:
	Time(int hour, int min, int sec)
		: _hour(hour)
		, _min(min)
		, _sec(sec)
	{
    
    }


private:
	int _hour;
	int _min;
	int _sec;
};

2 Precauciones

Cuando se inicializa el objeto, las variables miembro se inicializarán de acuerdo con la lista de inicialización (si hay un tipo personalizado, se llamará al constructor predeterminado correspondiente) y luego se ejecutará el contenido del cuerpo de la función. C ++ sabe cómo inicializar variables miembro según la lista de inicialización. Si no se muestra la lista de inicialización, la función generará la lista de inicialización correspondiente de forma predeterminada.

  1. Cada variable miembro solo puede aparecer una vez en la lista de inicialización (la inicialización solo puede aparecer una vez).
  2. La clase contiene variables miembro de referencia, variables miembro constantes y miembros de tipo personalizado (y cuando la clase no tiene un constructor predeterminado), deben colocarse en la lista de inicialización para la inicialización.
  3. El orden en que se declaran las variables miembro en la clase es el orden en que se inicializan en la lista de inicialización, independientemente de su orden en la lista de inicialización.

1~3

  1. Cada variable miembro en la lista de inicializadoressólo podemosOcurre una vez (la inicialización solo puede ocurrir una vez).
  2. la clase contieneVariables miembro de referencia, variables miembro constantes, miembros de tipo personalizado (y cuando la clase no tiene un constructor predeterminado), deben inicializarse colocándolos en la lista de inicializadores.

Si desea inicializar un tipo personalizado, primero debe asegurarse de que exista un constructor predeterminado para el tipo (tenga en cuenta cuál es el constructor predeterminado); de lo contrario, se informará un error, porque si la clase actual no tiene un tipo correspondiente constructor, el compilador llamará al constructor predeterminado de la función de clase para ejecutar. El código se muestra a continuación:

Para tipos personalizados

class Date 
{
    
    
public:

	// 重点在构造函数,其他不是重点
	// 全缺省才是默认构造函数
	//Date(int year=0, int month=0, int day=0)
	//{
    
    
	//	_year = year;
	//	_month = month;
	//	_day = day;
	//}

	Date&  operator=(const Date& d1)
	{
    
    
		_year = d1._year;
		_month = d1._month;
		_day = d1._day;
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};
class Time
{
    
    
public:
	Time(int hour=0, int min=0, int sec=0)
		: _hour(hour)
		, _min(min)
		, _sec(sec)
	{
    
    
	//在函数体初始化,比较麻烦,必须保证存在默认构造z函数
		Date t1;
		_d = t1;
	}


private:
	int _hour;
	int _min;
	int _sec;
	Date _d;
};


int main()
{
    
    
	Time t(6, 30, 30);
	return 0;
}

inserte la descripción de la imagen aquí

Si no se muestra el constructor predeterminado de la clase Date, el compilador no inicializará el valor de _d, que es un valor aleatorio. Por el contrario, si el trabajo de inicialización se escribe en la lista de inicialización, incluso si el constructor predeterminado no se muestra en la clase Fecha, el compilador inicializará el tipo personalizado de _d en 0.

class Date
{
    
    
public:
	Date& operator=(const Date& d1)
	{
    
    
		_year = d1._year;
		_month = d1._month;
		_day = d1._day;
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};

class Time
{
    
    
public:
	Time(int hour = 0, int min = 0, int sec = 0)
		: _hour(hour)
		, _min(min)
		, _sec(sec)
		,_d()
	{
    
    
	}

private:
	int _hour;
	int _min;
	int _sec;
	Date _d;
};


int main()
{
    
    
	Time t(6, 30, 30);
	return 0;
}

inserte la descripción de la imagen aquí


Para el tipo constante,
la variable miembro modificada const es una constante, no se puede asignar en el cuerpo de la función porque la constante no se puede modificar. Pero puedes inicializarlo en la lista o usar las características de C++ 11 para asignar un valor en la declaración.

inserte la descripción de la imagen aquí


Para tipos de referencia:
tipos de referencia, la referencia debe inicializarse cuando se define y no se puede reasignar, por lo que también debe escribirse en la lista de inicialización.

inserte la descripción de la imagen aquí

Este blog explica más detalladamente, consulte


  1. El orden en que se declaran las variables miembro en la clase es el orden en que se inicializan en la lista de inicialización , independientemente de su orden en la lista de inicialización.

Supongo que te gusta

Origin blog.csdn.net/weixin_45153969/article/details/132686616
Recomendado
Clasificación