resolucion programacion orientada operador objetos metodos ejemplos codigo clases ambito c++ g++

programacion - operador de resolucion de ambito c++



Inicializando el miembro const dentro de la declaraciĆ³n de clase en C++ (6)

Bueno, ¿no es exactamente una respuesta directa, sino una razón específica para no usar una macro?

#define tolerance 0.001 struct equal_vec { bool operator() (const Vector3D& a, const Vector3D& b) const { Vector3D dist = b - a; return ( dist.length2() <= tolerance ); } };

No es exactamente una buena práctica de C #, pero en mi humilde opinión es perfectamente legítima en C ++.

En PHP y C #, las constantes se pueden inicializar a medida que se declaran:

class Calendar3 { const int value1 = 12; const double value2 = 0.001; }

Tengo la siguiente declaración C ++ de un functor que se usa con otra clase para comparar dos vectores matemáticos:

struct equal_vec { bool operator() (const Vector3D& a, const Vector3D& b) const { Vector3D dist = b - a; return ( dist.length2() <= tolerance ); } static const float tolerance = 0.001; };

Este código compilado sin problemas con g ++. Ahora en el modo C ++ 0x (-std = c ++ 0x) el compilador g ++ genera un mensaje de error:

error: ''constexpr'' necesario para la inicialización en clase de la ''tolerancia'' del miembro de datos estáticos de tipo no integral

Sé que puedo definir e inicializar este miembro static const fuera de la definición de la clase. Además, un miembro de datos constantes no estáticos se puede inicializar en la lista de inicializadores de un constructor.

Pero, ¿hay alguna manera de inicializar una constante dentro de la declaración de la clase como es posible en PHP o C #?

Actualizar

Utilicé static palabra clave static simplemente porque era posible inicializar tales constantes dentro de la declaración de clase en g ++. Solo necesito una forma de inicializar una constante en una declaración de clase, no importa si se declara como static o no.


En C ++ 11, static miembros de datos no static , static constexpr miembros de datos de static constexpr y static const miembros de datos de static const de tipo integral o de enumeración se pueden inicializar en la declaración de clase. p.ej

struct X { int i=5; const float f=3.12f; static const int j=42; static constexpr float g=9.5f; };

En este caso, el i miembro de todas las instancias de la clase X se inicializa en 5 mediante el constructor generado por el compilador, y el miembro f se inicializa en 3.12 . El miembro de datos static const j se inicializa a 42 , y el miembro de datos de static constexpr está g se inicializa a 9.5 .

Como float y double no son de tipo integral o de enumeración, dichos miembros deben ser constexpr o no static para que se permita el inicializador en la definición de la clase.

Antes de C ++ 11, solo static const miembros de datos de static const de tipo integral o de enumeración podrían tener inicializadores en la definición de clase.


La inicialización de variables miembro estáticas que no sean tipos const int no es C ++ estándar anterior a C ++ 11. El compilador de gcc no lo advertirá sobre esto (y producirá código útil) a menos que especifique la opción -pedantic . Debería obtener un error similar a:

const.cpp:3:36: error: floating-point literal cannot appear in a constant-expression const.cpp:3:36: warning: ISO C++ forbids initialization of member constant ‘tolerance’ of non-integral type ‘const float’ [-pedantic]

La razón de esto es que el estándar de C ++ no especifica cómo se debe implementar el punto flotante y se lo deja al procesador. Para evitar esta y otras limitaciones, se introdujo constexpr .


Me encontré con problemas reales con esto, porque necesito el mismo código para compilar con las diferentes versiones de g ++ (el compilador GNU C ++). Así que tuve que usar una macro para ver qué versión del compilador estaba siendo utilizada, y luego actuar en consecuencia, como tal

#if __GNUC__ > 5 #define GNU_CONST_STATIC_FLOAT_DECLARATION constexpr #else #define GNU_CONST_STATIC_FLOAT_DECLARATION const #endif GNU_CONST_STATIC_FLOAT_DECLARATION static double yugeNum=5.0;

Esto usará ''const'' para todo antes de la versión 6.0.0 de g ++ y luego usará ''constexpr'' para la versión 6.0.0 y superior de g ++. Esa es una conjetura sobre la versión donde se lleva a cabo el cambio, porque francamente no lo noté hasta la versión 6.2.1 de g ++. Para hacerlo bien, puede que tenga que mirar la versión menor y el número de parche de g ++, así que vea

https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html

para los detalles sobre las macros disponibles.

Con gnu, también puedes -fpermissive con el uso de ''const'' en todas partes y luego compilar con la bandera -fpermissive , pero eso da advertencias y me gusta que mis cosas se compilen limpiamente.

No es genial, porque es específico de los compiladores gnu, pero sospecho que podría hacer algo similar con otros compiladores.


Sí. Simplemente agregue la palabra clave constexpr como dice el error.


Si solo lo necesita en un método, puede declararlo localmente estático:

struct equal_vec { bool operator() (const Vector3D& a, const Vector3D& b) const { static const float tolerance = 0.001f; Vector3D dist = b - a; return ( dist.length2() <= tolerance ); } };