una que programacion poo orientada objetos objeto miembros metodos ejemplos clases clase atributos atributo c++ c++11

c++ - que - ¿Por qué es necesario un constructor en una estructura miembro?



que es un objeto en programacion (2)

Tengo un código similar a esto:

class AClass { public: struct AStruct { }; AClass(){} private: const AStruct m_struct; }; int main() { AClass a; }

Lanza este error de compilación (con Clang LLVM versión 5.1):

error: constructor for ''AClass'' must explicitly initialize the const member ''m_struct''

Si especifico un constructor predeterminado de C ++ 11 para struct AStruct , recibo el mismo error:

struct AStruct { AStruct() = default; };

Sin embargo, esto se resuelve escribiendo un constructor con un cuerpo vacío:

struct AStruct { AStruct(){} // fixed };

¿Por qué necesito especificar un constructor vacío? ¿No se creó automáticamente con acceso público para las estructuras?

¿Por qué el constructor por defecto de C ++ 11 no resuelve el problema?


De §8.5 [dcl.init] / 7:

Si un programa solicita la inicialización predeterminada de un objeto de un tipo const-calificado T, T será un tipo de clase con un constructor predeterminado proporcionado por el usuario.

El constructor predeterminado de AClass predeterminado: inicializa el miembro const (ver a continuación), por lo que el miembro debe tener un constructor predeterminado proporcionado por el usuario. El uso = default no da como resultado un constructor predeterminado proporcionado por el usuario, como se puede ver en §8.4.2 [dcl.fct.def.default] / 4:

Una función es proporcionada por el usuario si es declarada por el usuario y no está explícitamente predeterminada o eliminada en su primera declaración.

El miembro se inicializa por defecto según §12.6.2 [class.base.init] / 8:

En un constructor no delegante, si un miembro de datos no estático determinado o clase base no está designado por un identificador-inicializador-memoria (incluido el caso donde no hay lista-inicializador-mem porque el constructor no tiene inicializador-ctor) y la entidad no es una clase base virtual de una clase abstracta (10.4), entonces

- si la entidad es un miembro de datos no estático que tiene un inicializador de llave o igual, la entidad se inicializa como se especifica en 8.5;
- de lo contrario, si la entidad es una unión anónima o un miembro de la variante (9.5), no se realiza ninguna inicialización;
- de lo contrario, la entidad se inicializa por defecto (8.5).


Robado de la respuesta de @ Chris tenemos este párrafo: §8.5 [dcl.init] / 7:

Si un programa solicita la inicialización predeterminada de un objeto de un tipo const-calificado T, T será un tipo de clase con un constructor predeterminado proporcionado por el usuario.

Entonces podemos construir un caso completamente ridículo que ilustra esta restricción:

struct Foo {}; int main() { const Foo f; }

que no compila en clang, como dicta la norma. Su código es simplemente esto, pero como una variable miembro de otra clase / estructura.

Incluso podemos hacer esto:

struct Foo {int x = 3;}; int main() { const Foo f; }

donde todos los datos son obviamente inicializados. Este último ejemplo me convence de que esto es un defecto en el estándar.

La idea probablemente sea algo relacionado con los tipos de POD no inicializados y const , pero la redacción bloquea el código que no está relacionado. Los constructores por defecto en C ++ moderno a menudo son más que suficientes, y forzar a Foo(){} es de una forma pobre.