100 likes | 193 Views
Const member functions. Frequentemente construimos funções cujo objectivo é aceder a um objecto sem o alterar (seja público ou privado). Nesse caso é preciso dar indicação ao leitor humano que assim é criando funções membro constantes . Exemplo de alteração na classe node:
E N D
Const member functions • Frequentemente construimos funções cujo objectivo é aceder a um objecto sem o alterar (seja público ou privado). Nesse caso é preciso dar indicação ao leitor humano que assim é criando funções membro constantes. Exemplo de alteração na classe node: dist getDistance(node& myNode) const; Neste caso a função getDistance fornece a distância sem poder alterar myNode. Se tivessemos const dist getDistance(node& myNode) const; o resultado também não poderia ser alterado Curso C++ (J. Seixas)
Const member functions • O overloading the funções membro const tem algumas características especiais: class Node { public: Node(); // Create uninitialized Node(coord x, coord y); // Create from (x,y) dist getDistance(Node point) const; // Distance to another point distance getDistance(Row line) const; // Distance to a line coord& x(); // Reference to x-coordinate coord x() const; // Get x-coordinate coord& y(); // Reference to y-coordinate coord y() const; // Get y-coordinate ang angle(Point p1, Point p3) const; private: coord the_x; // x-coordinate coord the_y; // y-coordinate }; #include <iostream.h> #include “Node.h" static void f() { Node p1(2, 3); cout << p1.x() << endl; // Uses non-const x() p1.x() = 1; // Uses non-const x() p1.y() = 2; // Uses non-const y() const Node p2 = p1; cout << p2.x() << endl; // Uses const x() /* p2.x() = 3;// WRONG: Operand of = must be an lvalue (Uses const x()) p2.y() = 4;// WRONG: Operand of = must be an lvalue (Uses const x()) */ Curso C++ (J. Seixas)
Templates • A noção de overloading é interessante, mas requer ainda assim a definição de várias versões de funções e classes. Para fazer uma programação genérica o C++ inclui a noção de template. Exemplo para classes: template <class Type>class Queue{ public: Queue(); Type &front() const; void push(const Type &); void pop(); bool empty() const; private: …. } em vez de class pode-se usar também a keyword typename na definição do template. Para usar o template faz-se por exemplo a declaração Queue<int> qi Curso C++ (J. Seixas)
Templates • Templates podem ser usados também só com funções template <typename T> int compare(const T &v1, const T &v2){ if(v1 < v2) return -1; if(v2 < v1) return 1; return 0; } e pode haver mais do que uma indicação de template template <typename T, typename Other, …> Curso C++ (J. Seixas)
Templates • As funções inline têm de ser declaradas como template <typename T> inline T min(const T&, const T&); É errado pôr: inlinetemplate <typename T> T min(const T&, const T&); • A propósito: ao contrário do que é costume, as funções inline devem ser definidas nos header files. A razão é que o compilador necessita da definição para expandir a função. O protótipo apenas é insuficiente! Curso C++ (J. Seixas)
Templates • Os parâmetros de template têm escopo da declaração de template: typedef double T; template <class T> T calc(const T& a, const T& b){ T tmp=a; return tmp; } tmp tem p tipo definido por <class T> NÃO o double definido pelo typedef global. O nome do parâmetro de template não pode ser redefinido por typedef dentro do escopo. Curso C++ (J. Seixas)
Templates • Os parâmetros de template não têm de ser necessariamente uma indicação de tipo. Exemplo: template <class T, size_t N> void array_init(T (&parm) [N]){ for(size_t i=0; I != N; ++i){ parm[i] = 0; } } N é aqui uma constante especial: int x[42]; double y[10]; array_init(x); // instancia array_init(int(&)[42]) array_init(y); // instancia array_init(double(&)[10]) Curso C++ (J. Seixas)
Gestão dinâmica de memória • A gestão dinâmica de memória em C++ é feita usando newe delete. Por exemplo, para criar um vector de inteiros: int *vec = new int[n_elem]; if(!vec) error("Unable to allocate memory for vec.", 1); memset(vec,0,n_elem*sizeof(int)); … delete[] vec; Curso C++ (J. Seixas)
Gestão dinâmica de memória • As nossas velhas amigas matrizes: int **mat=new (int*)[n_lin]; mat[0]=vector(n_lin*n_col); // all matrix memory in one row if(!(mat[0])) error("Unable to allocate memory for mat.", 2); for(int i=0; i < n_lin ;++i) mat[i]=mat[0]+(i*n_col); // each new line starts n_col ahead memset(mat[0],0, n_lin*n_col*sizeof(int)); … delete[] mat[0]; delete[] mat; Curso C++ (J. Seixas)
Sem [] ! Gestão dinâmica de memória • Exemplo com a classe node: node* point2D3=new node; point2D3->setCoordinates(3,4); cout << "Novo nodo, distancia a linha 2: " << point2D3->getDistance(Line2) << endl; cout << "Novo nodo, distancia ao nodo 2: " << point2D3->getDistance(point2D2) << endl; delete point2D3; O operador [] em delete é apenas usado quando criamos variáveis dimensionadas! Curso C++ (J. Seixas)