Inicialización de la matriz de objetos de clase
-
25-10-2019 - |
Pregunta
¿Hay alguna forma de inicializar una matriz así:
static const vec3d<long> XI[Q] = {
vec3d<long>( 0, 0, 0 ),
vec3d<long>(-1, 0, 0 ), vec3d<long>( 0,-1, 0 ), vec3d<long>( 0, 0,-1 ),
vec3d<long>(-1,-1, 0 ), vec3d<long>(-1, 1, 0 ), vec3d<long>(-1, 0,-1 ), [etc]
};
dónde
00039 template<typename TYPE>
00040 class vec3d : public vec<TYPE>{
00041 public:
00042
00049 vec3d() : vec<TYPE>( 0, 3 ){};
00057 vec3d( TYPE right ) : vec<TYPE>( right, 3 ){};
00065 vec3d( TYPE X_val, TYPE Y_val, TYPE Z_val ) : vec<TYPE>( 0, 3 ){
00066 this->val[0] = X_val;
00067 this->val[1] = Y_val;
00068 this->val[2] = Z_val;
00069 };
00077 vec3d( vec3d<TYPE>& right ) : vec<TYPE>( 0, 3 ){
00078 this->val[0] = right[0];
00079 this->val[1] = right[1];
00080 this->val[2] = right[2];
00081 }; [etc] };
y
00040 template<typename TYPE>
00041 class vec{
00042 public:
00047 TYPE *val;
00052 int dimension;
00053 public:
00060 vec();
00066 vec( TYPE right );
00073 vec( TYPE right, int _dimension );
00081 vec( vec<TYPE> &right );
00082
00087 ~vec();
00088
00089
00090 TYPE& operator[]( int right);
00091 vec<TYPE>& operator=( TYPE right );
00092 vec<TYPE>& operator=( vec<TYPE> &right );
[etc] };
La fuente es:
00049 template<typename TYPE>
00050 vec<TYPE>::vec( TYPE right, int _dimension ){
00051 dimension = _dimension;
00052 val = new TYPE[_dimension];
00053 assert( val );
00054 for( int i = 0; i < dimension; i++ ) val[i] = right;
00055
00056 };
00075 template<typename TYPE>
00076 TYPE& vec<TYPE>::operator[]( int right ){
00077 assert( ( right < dimension ) );
00078 assert( right >= 0 );
00079 assert( val );
00080 return val[right];
00081 };
son constructores. Q se declara "estática const int", por lo que debería cumplir con el estándar C ++ de no ser variable, ¿verdad?
El compilador dice: Error: No hay función coincidente para la llamada a 'Albm :: VEC3D :: VEC3D (ALBM :: VEC3D)' VEC3D.H: 77: 2: NOTA: Los candidatos son: albm :: vec3d :: vec3d (albm :: vec3d &) [con type = long int
Obviamente existe el problema, que no puedo pasar VEC3D y aquí. ¿Hay alguna solución? Definir cada vector primero parece ser una solución. Sin embargo, sería un lágrano ...
Y perdón por mi estúpida pregunta ... tal vez este hilo existe en alguna parte, pero no lo encontré. Probablemente este problema tiene un nombre especial que no conozco, ¡por lo tanto no puedo buscarlo en Google! "Lista de inicializador extendida", "Inicialización de la matriz de clases" y tal no hizo el truco ...
SOLUCIÓN: Algunos posprocesos aquí ... tal vez así. Else se encuentra con el mismo problema: el constructor de copias carecía de un "const":
00077 vec3d( const vec3d<TYPE>& right ) : vec<TYPE>( 0, 3 ){
00078 this->val[0] = right.val[0];
00079 this->val[1] = right.val[1];
00080 this->val[2] = right.val[2];
Además, no puedo acceder bien [] directamente, supongo que por una razón sería el estilo de la plantilla, pero correcto.val [] hace el truco!
Solución
Su copia y constructor no se declara correctamente: el parámetro TOCOPYFROM es necesario estúpido:
vec3d<TYPE>( const vec3d<TYPE>& toCopyFrom)
Editar:
Ahora, en su segundo problema con respecto al operador de subíndice:
El operador de subíndice operator[]()
en tu clase base no tiene const
(es decir, solo lectura) Semántica. En su constructor de copias, estaba tratando de acceder a los valores en right
a través de ese operador de subíndice. Ahora eso right
El parámetro se declara const, lo que básicamente significa que no se le permite cambiar el estado interno de right
. Ya que tu operator[]()
la función no es const, la suposición del lenguaje es que la función podría mutar/alterar el estado de right
- ¿Qué conflicto con right
'S Const -ness. De hecho, la función realmente devuelve una referencia a las variables de miembro interno de la clase, lo que permitiría que un cliente de ese código cambie el estado interno de right
!
La solución es proporcionar un operador de subíndice adicional, const en la clase base:
const TYPE& operator[]( int right) const
Nota - Personalmente, cambiaría el nombre right
a index
- para mayor claridad.
El final const
En la función de la función anterior, le proporciona una semántica de acceso constante, que le permite llamar, por ejemplo, x = right[n]
cuando right
es const
. El constante principal en el tipo de retorno solo significa que la referencia de tipo devuelta será const, lo que le impide hacer right[n] = x
cuando right
es const. Nota: cuando agrega la función, su implementación (cuerpo) de la función probablemente debería verse lo mismo que para el operador de subíndice existente. No proporcionaste eso, así que no puedo escribirlo.
En conclusión, le sugiero que lea sobre los temas de const y 'corrección de const corrientes'.
Otros consejos
Dado
00039 template<typename TYPE>
00040 class vec3d : public vec<TYPE>{
00041 public:
00042
00049 vec3d() : vec<TYPE>( 0, 3 ){};
00057 vec3d( TYPE right ) : vec<TYPE>( right, 3 ){};
00065 vec3d( TYPE X_val, TYPE Y_val, TYPE Z_val ) : vec<TYPE>( 0, 3 ){
00066 this->val[0] = X_val;
00067 this->val[1] = Y_val;
00068 this->val[2] = Z_val;
00069 };
00077 vec3d( vec3d<TYPE>& right ) : vec<TYPE>( 0, 3 ){
00078 this->val[0] = right[0];
00079 this->val[1] = right[1];
00080 this->val[2] = right[2];
00081 }; [etc] };
El constructor de copias definido en la línea 77 no tieneconst
argumento, que no puede estar vinculado a un argumento de rValue.
Simplemente elimine las líneas 77 a 81.
El compilador generará un buen constructor de copias para usted.
Saludos y hth.,