2011-10-21 18 views
10

que tienen una tarea que me pide que haga lo siguiente:Uso de plantillas en C++

Diseño una clase de plantilla llamada FlexArray que ofrece variedad flexibles índices. El usuario de la clase puede establecer el índice inferior y el índice superior cuando se declara el objeto.

Ejemplos de código de usuario:

FlexArray un (1,5); // el índice más bajo es 1 y el índice superior es 5 FlexArray b (-5, 10); // índice inferior es -5 y el índice superior es 10

proporcionar las siguientes funciones para su clase:

  1. constructor predeterminado
  2. constructor parametrizado en el que el usuario especifica menor índice y el índice superior
  3. destructor
  4. constructor de copia
  5. operador de asignación
  6. operador [] sobrecargado con una semántica similar a [] ya utilizado con matrices incorporadas.

Los errores en las condiciones de PRE se pueden manejar con sentencias de afirmación o try/catch blocks. No hay cambio de tamaño de la matriz ofrecida. Los subíndices deben estar dentro del rango.

El libro no es realmente útil para crear plantillas. Esperaba que alguien me diera alguna dirección sobre este problema y para ver si mi código está en el camino correcto. He tratado de iniciar este problema por el alcance muy limitado de los libros y diferentes recursos en línea y tengo:

#ifndef H_templates 
#define H_templates 

#include <iostream> 
using namespace std; 

template <typename T>   
class FlexArray 
{ public:     
    FlexArray();   // POST: empty FlexArray 
    FlexArray(LI,UI);    // POST: Parameterized Constructor 
    ~FlexArray();   // POST: destructor 
    CopyArr(Array* sourceArray, Array* destinationArray, size);    // POST: Copies array 

    //Overloading the assignment operators to add arrays(?) Unsure if 
    // this is what is meant by the original question 
    FlexArray operator+ 
     (const FlexArray& otherFlexArray) const; 
     //Overload the operator + 
    FlexArray operator- 
     (const FlexArray& otherFlexArray) const; 
     //Overload the operator - 
    FlexArray operator[] 
     (const FlexArray& otherFlexArray) const; 
     //Overload the operator [] 

private: 
    T FlexArray[size];  // Flex array 
    int size;    // number of items Array 
    int LI;     //Lower Index 
    int UI;     //Upper Index 
}; 

template <typename T> 
FlexArray<T>::FlexArray() 
// POST: empty FlexArray 
{ size = 0; } 

template <typename T> 
FlexArray<T>::~FlexArray() 
// POST: destructor 
{ } 
template <typename T> 
FlexArray<T>::CopyArr(Array* sourceArray, Array* destinationArray, size) 
//Pre: Takes 3 arguments, the original array, the array to copy too, and, the size of array 
// POST: Copies the array 
{ 
    for(int i=0; i<size; i++){ 
     sourceArray[i] = destinationArray[i] 
    } 
} 

#endif 
+1

El operador de asignación es 'operator ='. –

+2

+1 para declarar la tarea! – Marlon

+0

Una plantilla en C++ es una familia de objetos, con las mismas características pero que aloja diferentes objetos. Por ejemplo, use plantillas para apilamientos, colas, listas. NO PARA COSAS QUE TIENEN "UNA RELACIÓN CON; (como formas/rectángulos/cuadrados/círculos ...) –

Respuesta

6

Has tenido un buen comienzo. Un par de cosas para señalar.

La asignación solicita un constructor predeterminado, PERO también indica que no se admite el cambio de tamaño de la matriz. Estos dos requisitos entran en conflicto lógicamente: su suposición (para usar size=0) parece lógica, pero este objeto construido por defecto siempre estará vacío. No es un gran problema, solo una desconexión lógica en los requisitos.

Un constructor paramaterizado que toma los límites superior e inferior. Usted ha comenzado en esto como:

FlexArray(LI,UI);    // POST: Parameterized Constructor 

Sin embargo, LI y UI necesitarán tipos. Como debe admitir índices negativos, debe ser un tipo firmado, como int.

Un constructor de copias, es un constructor que toma un objeto del mismo tipo. No has declarado uno de estos. Debe tener la forma:

FlexArray(const FlexArray&); 

El operador de asignación es el operador = que le permite hacer esto:

FlexArray a, b; 
b = a; 

No ha declarado uno de estos. Se debe tomar la forma:

FlexArray& operator=(const FlexArray&); 

La implementación será similar al constructor de copia (de hecho, el constructor copia, simplemente se podría implementar en términos del operador de asignación).

Operador sobrecargado []. Usted ha declarado uno de estos, pero en realidad no está en la forma correcta, no toma los tipos de argumentos apropiados. El uso se verá así:

FlexArray arr(-5, 10); 

// This is a call to operator[] 
arr[3] = value; 

Dado que, trate de pensar qué tipo de argumento debería tomar.

Ahora, a los requisitos funcionales. Dado un límite superior e inferior, debe crear una matriz que pueda indexarse ​​utilizando esos límites. Piensa en lo que necesitas saber para poder hacer eso. Sugeriré que necesites saber la diferencia del límite superior e inferior (este será el TAMAÑO de tu matriz).Debería verificar en el constructor que el límite superior es mayor que el límite inferior, o no puede crear efectivamente este conjunto.

Ahora, para construir realmente su conjunto de objetos, necesitará asignar dinámicamente algo de memoria para ellos. Intente esto con:

T FlexArray[size];  // Flex array 

Pero esto tiene algunos problemas. En primer lugar, no creo que pueda ponerle el nombre FlexArray, ya que colisionará con el nombre de su clase. En segundo lugar, esto requiere que size sea una constante de tiempo de compilación, que infringe nuestros requisitos. Por lo tanto, deberá asignar dinámicamente la matriz interna de objetos T (utilizando new si aún no ha aprendido sobre los punteros inteligentes). Recuerde desasignar esta matriz de objetos en su destructor.

Ahora, funcionalmente, ¿cómo funcionará el []? El requisito es hacer la comprobación de límites, por lo que, dado un índice, debe saber si es demasiado bajo (fuera del límite inferior) o demasiado alto (fuera del límite superior) y generar un error apropiado. Ahora tiene un conjunto de objetos T dinámicamente asignados (0-based), dado un índice que es especificado por el usuario, necesita encontrar el objeto apropiado para devolver. Piense en cómo hacer que eso suceda.

Además, ha declarado + y - operadores, aunque el requisito no especifica que deberían estar allí. Sugeriría sacarlos. El operador + implica que la matriz se redimensionará (lo cual se contradice con los requisitos) y - es ambigua, ¿qué significa restar dos matrices? Ambas funciones podrían ser válidas, pero para esta tarea son innecesarias.

No hay más sugerencias :)

+0

Gracias, esto es muy útil. Para el constructor de copias, ¿dónde/cómo escribo realmente la parte de copia para una plantilla? Sé en anteriores hw's cuando sobrecargamos algo, escribimos la función en su propio archivo .cpp, pero parece que muchos elementos relacionados con las plantillas se guardan en el archivo de encabezado o puede que ni siquiera importe. Así que me gusta: 'FlexArray :: operator = (const FlexArray &) const { \t \t \t // ¿un código para copiar el código? \t} ' – Nick

+0

Sí, las plantillas tienen todo el código en el archivo de encabezado (generalmente), y usted tiene la sintaxis básica correcta. – Chad

+0

También - respuesta actualizada con un par de cosas más ... – Chad

0

Bueno, lo primero que noto de buenas a primeras es que realmente no tiene una copia constructor. Si pensabas que CopyArr califica, no es así. La sintaxis debe estar en los materiales de tu clase, pero básicamente es un constructor que toma una referencia const a la clase como su único parámetro.

Tampoco tiene un operador de asignación (también conocido como: asignación de copia). Nuevamente, la sintaxis exacta debe estar en los materiales de su clase, pero el nombre de la rutina sería operator=.

Además, su operador de array no me parece tener "semántica similar a [] ya utilizada con matrices integradas". Una matriz incorporada devuelve el tipo de elemento (que sería T en su caso, ¿no?), Pero el suyo devuelve el tipo completo FlexArray.

En cuanto al desarrollo de la plantilla en sí, esto es lo que sugiero si tiene problemas. Comience desarrollando todo para que funcione como una clase simple (sin plantilla) con un tipo simple (por ejemplo: int). Haz que se pruebe y verifique que funcione de esa manera. Luego transfórmalo en una plantilla. Rastrear los errores dentro de las plantillas puede ser un desafío incluso para los desarrolladores experimentados.

+0

Un constructor de copia * no * simplemente está sobrecargando el operador '='. Consulte http: //en.wik ipedia.org/wiki/Copy_constructor. Es un verdadero constructor. Se llama implícitamente cuando asigna una instancia del objeto (nota: no solo un puntero sino el objeto mismo) o cuando pasa una instancia del objeto a un método. –

+0

Oh, traté de escribir una función de copia vs sobrecargar el operador '=' – Nick

+0

@JackEdmonds - Lo siento. Eso fue un breif brain-fart. Solucionado antes de que viera tu comentario. Definitivamente digno de -1 mientras estuvo allí. C++ es lo suficientemente fuerte como para aprender sin confundir el pobre OQ con la terminología equivocada. –

0

Como otras respuestas no han entrado en esto, hay algunas cosas extrañas sobre: ​​

template <typename T> 
FlexArray<T>::CopyArr(Array* sourceArray, Array* destinationArray, size) 
//Pre: Takes 3 arguments, the original array, the array to copy too, and, the size of array 
// POST: Copies the array 
{  
    for(int i=0; i<size; i++){ 
     sourceArray[i] = destinationArray[i] 
    } 
} 

El parámetro size necesitaría un tipo así como un nombre.

Ha hecho que sea una función miembro de un objeto y, sin embargo, no funciona en ese objeto en absoluto. Solo opera en los objetos pasados ​​en los parámetros. En su lugar, podría hacer que esa función acepte una matriz (la que se va a copiar). Llámalo assign. Luego puede usarlo para implementar su copy constructor y operator=.

La otra rareza es el tipo Array. ¿Dónde está eso definido?

+0

Whoops :) no está definido en ningún lado. Estaba viendo un ejemplo en el libro, ¿podría usar 'CopyArr (sourceArray [], destinationArray [], size)'? – Nick

+0

¿Con qué compilador ejecuta su código mientras lo escribe? (Esta es una pregunta cargada!) –

+0

Uso MS Visual C++ 2010 para editar y compilar. – Nick

0

Desea la asignación dinámica. La forma más sencilla de hacerlo es usar un std::vector.

+0

Acabamos de utilizar vectores en clase el otro día, así que sé que es relevante para la tarea. Podrías expandir tu respuesta un poco. – Nick

+0

Este es un buen punto, pero es posible que la intención de la pregunta sea que usted asigne el almacenamiento con 'new' y' delete' ya que no habría razón para escribir su propio constructor de copia, destructor, etc., si usa 'std :: vector' para su almacenamiento. Los valores predeterminados se encargarían de todo por ti. –

+1

No estoy tan seguro, ya que esto era tarea. Sería bastante posible hacerlo con una matriz y lanzar una excepción si el usuario solicita límites demasiado separados. Pero si el maestro de @ Nick acaba de presentar los vectores, podría serle útil ir a preguntarle al maestro por una pista si debería usar uno aquí ... –

Cuestiones relacionadas