una resueltos programacion orientada objetos miembros metodos ejercicios ejemplos constructores codigo clases clase atributos c++ initialization-list

c++ - resueltos - ¿Se pueden usar las funciones miembro para inicializar las variables miembro en una lista de inicialización?



miembros de una clase en programacion orientada a objetos (2)

Sí, su uso de la función miembro en la lista de inicialización es válido y cumple con el estándar.

Los miembros de los datos se inicializan en el orden de su declaración (y esa es la razón por la que deberían aparecer en la lista de inicialización en el orden de su declaración, la regla que siguió en su ejemplo). N_ se inicializa primero y podría haber pasado este miembro de datos a fill_arr . Se llama a fill_arr antes que al constructor, pero como esta función no accede a miembros de datos no inicializados (no accede a miembros de datos en absoluto), su llamada se considera segura.

Aquí hay algunas excepciones relevantes del último borrador (N3242 = 11-0012) del estándar C ++:

§ 12.6.2.13: Las funciones miembro (incluidas las funciones miembro virtuales, 10.3) pueden llamarse para un objeto en construcción. (...) Sin embargo, si estas operaciones se realizan en un inicializador ctor (o en una función llamada directa o indirectamente desde un inicializador ctor) antes de que se hayan completado todos los inicializadores de memoria para las clases base, el resultado de la operación no está definido. Ejemplo:

class A { public: A(int); }; class B : public A { int j; public: int f(); B() : A(f()), // undefined: calls member function // but base A not yet initialized j(f()) { } // well-defined: bases are all initialized }; class C { public: C(int); }; class D : public B, C { int i; public: D() : C(f()), // undefined: calls member function // but base C not yet initialized i(f()) { } // well-defined: bases are all initialized };

§12.7.1: para un objeto con un constructor no trivial, refiriéndose a cualquier miembro o clase base no estática del objeto antes de que el constructor comience a ejecutar los resultados en un comportamiento indefinido. Ejemplo

struct W { int j; }; struct X : public virtual W { }; struct Y { int *p; X x; Y() : p(&x.j) { // undefined, x is not yet constructed } };

OK, las variables miembro pueden usarse para inicializar otras variables miembro en una lista de inicialización (teniendo cuidado con el orden de inicialización, etc.). ¿Qué pasa con las funciones de los miembros? Para ser específico, ¿este fragmento es legal de acuerdo con el estándar C ++?

struct foo{ foo(const size_t N) : N_(N), arr_(fill_arr(N)) { //arr_ = fill_arr(N); // or should I fall back to this one? } std::vector<double> fill_arr(const size_t N){ std::vector<double> arr(N); // fill in the vector somehow return arr; } size_t N_; std::vector<double> arr_; // other stuff };


Al inicializar objetos en la lista de inicialización, el objeto aún no está completamente construido.
Si esa función intenta acceder a la parte del objeto que aún no está construido, entonces ese es un comportamiento indefinido, de lo contrario está bien.
ver esta respuesta