Cátedra: Veiga
Fecha: 1er Cuatrimestre 2007
Día: 10/07/2007
Tema: 2
La razón que obliga a que esa función sea estática es que la implementación para manejo de Threads que debía ser utilizada (pthreads) requiere un puntero a función para la creación de un nuevo Thread. Dicho puntero es el que especifica qué función debe correrse cuando se inicie la ejecución del thread. Dado que las funciones estáticas no tienen la estructura de un método miembro de clase (es decir, no reciben un parámetro “this” implícito), sino que tienen la firma de una función standard (Plain C-style) pueden ser referenciadas por un puntero común. Otro motivo es que los punteros a función no pueden referirse a funciones miembro, ya que no se posee una referencia al área de memoria en que se encuentrasu código directamente, sino una referencia a una virtual-table y a un offset.
Al implementar el operador = para una clase que utiliza memoria dinámica, debe tenerse en cuenta que el lvalue (left value, o sea, el objeto al que se le va a asignar el valor) posiblemente haya reservado memoria, por lo que perder la referencia a ese sector, puede derivar en un memory leak. En estos casos, debe desalocarse la memoria del lvalue antes de hacer que sus punteros referencien a los nuevos valores (siempre que sea la clase responsable de alocar la memoria referenciada por los punteros).
class String { public: explicit String(int length); /* El constructor alocará memoria mediante new[], usando la longitud como parámetro */ ~String(); /* El destructor llamará a delete[] */ String& operator=(const String& s) { delete[] string; /* Desreservo la memoria antes de perder la referencia */ string = s.string; } /* Más métodos útiles */ private: char* string; };
/** * Archivo: main.c * Si el archivo no fuese un archivo fuente, sino uno de encabezados (.h), la definicion de X seria accesible desde afuera **/ /* Una definición de una variable entera sin signo, global, no visible fuera del fuente llamada X. */ static unsigned int X = 3; /* Una declaración de una función llamada MiFuncion que tome un arreglo de enteros y devuelva un puntero a caracter. */ char* MiFuncion(int arregloEnteros[]); /* Una definición de la funcion main */ int main(int arg,char** argv) { printf("%s","Hello World!"); return 0; }
#ifndef ALUMNO_H_ #define ALUMNO_H_ #include <string> #include <istream> /* * Incluya al menos: Constructor default. * Constructor con valor de inicializacion * Constructor de copia: Operador <, ==, =, int y » (carga del STDIN). * Implemente el operador». * */ class Alumno { private: std::string name; unsigned int code; float average; public: Alumno() {} Alumno(std::string name, unsigned int code); Alumno(const Alumno&); bool operator<(const Alumno&) const; bool operator==(const Alumno&) const; Alumno& operator=(const Alumno&); operator int() const; /* Getters y Setters */ void addSubject(float ); friend std::istream& operator >> (std::istream& is, Alumno& alumno); }; std::istream& operator>>(std::istream& is, Alumno& alumno) { char input[256]; is.getline(input, 256); char* pch; pch = strtok (input,","); if (pch != NULL) { alumno.name = pch; pch = strtok (NULL, ","); if (pch != NULL) { alumno.code = atoi(pch); pch = strtok(NULL,","); if (pch != NULL) { alumno.average = atof(pch); } } } return is; } #endif
El sufijo const en la declaración de un método indica que durante su ejecución no modificará los valores de los miembros, ni hará llamados a métodos que no estén indicados también como const. En tiempo de compilación, se verifica que esto sea así (aunque un casteo explícito de this a una referencia no constante puede permitir que se saltee la restricción, no hay forma de que pase por error)