funciones externas c++ constructor language-lawyer object-lifetime

C++: duración de un objeto y funciones externas



funciones en c++ (1)

Supongamos que quiero llamar a una función externa de mi objeto para realizar algunas comprobaciones dentro del constructor del cuerpo. Dado que la vida útil de un objeto comienza cuando el cuerpo del constructor termina su ejecución, ¿se trata de un diseño inseguro?

struct A; void check(A const&) { /* */ } struct A { A() { check(*this); } };

Quiero decir, estoy llamando y la función externa con un objeto aún no vivo. ¿Es un comportamiento indefinido?

Preguntas relacionadas: si pongo esa función de verificación como función miembro (estática o no), ¿qué dice el estándar sobre el uso de objetos aún no vivos fuera del constructor pero dentro de la clase?

¿Hay alguna diferencia en el concepto de la vida entre el punto de vista de una clase y sus usuarios (una especie de vidas dentro de clase versus fuera de clase)?


La vida útil de A no habrá comenzado cuando se llame a check() porque, desde [base.life]:

La vida útil de un objeto de tipo T comienza cuando:

  • se obtiene el almacenamiento con la alineación y el tamaño adecuados para el tipo T , y
  • si el objeto tiene una inicialización no vacía, su inicialización está completa.

A tiene una inicialización no vacía. Su inicialización está completa cuando, desde [class.base.init] / 13:

En un constructor no delegante, la inicialización procede en el siguiente orden:

  • ...
  • - Finalmente, se ejecuta la sentencia compuesta del cuerpo constructor.

Sin embargo, a pesar de que A no ha comenzado toda su vida, la norma también proporciona, en [class.base.init] / 16:

Las funciones de miembro (incluidas las funciones miembro virtual, 10.3) pueden invocarse para un objeto en construcción ... Sin embargo, si estas operaciones se realizan en un inicializador de ctor (o en una función llamada directa o indirectamente desde un inicializador de ctor ) antes de todo los iniciadores de memoria para las clases base se han completado, el resultado de la operación no está definido.

Con respecto a los problemas de la vida, no hay diferencia entre:

void check(const A& ) { .. } struct A { A() { check(*this); } };

Y:

struct A { void check() const { .. } A() { check(); } };

Este último está explícitamente permitido (ya que no está en un ctor-inicializador ), por lo que no veo ninguna razón para excluir el primero por motivos de por vida.