Enviado em 29/09/2016 - 14:27h
Galera alguém poderia me explicar como funciona as funçoes as quais trabalham com endereços const como por exemplo:vectorx& vectorx::operator*(const int& n);
Enviado em 30/09/2016 - 03:34h
vectorx& vectorx::operator*(const int& n);
int a=0; int &ra=a; int *pa=&a; ++a; ++ra; ++*pa;
// As duas versões podem ter o mesmo nome porque os argumentos são diferentes! void swap(int *v1, int *v2){ int temp=*v1; *v1=*v2; *v2=temp; } void swap(int &v1, int &v2){ int temp=v1; v1=v2; v2=temp; } int main(){ int a=1, b=2; swap(&a, &b); // Explicitamente passo os endereços como argumentos. // Aqui, a==2 e b==1. swap(a, b); // O compilador se encarrega de obter endereços e passá-los. // Agora, a==1 e b==2 novamente. }
void triplica(int *pi){ (*pi)*=3; // Inseguro: função pode dar pau se pi for nulo ou inválido. } void triplica(int &ri){ ri*=3; // Seguro (no que diz respeito à função). } int main(){ int a=1; triplica(&a); // OK: eu passo um endereço de um objeto válido. tiplica(a); // OK: referência sempre é válida. int *pa=nullptr; triplica(pa); // Chamada é sintaticamente válida, mas vai dar pau dentro da função! triplica(*pa); // Essa feitiçaria também é sintaticamente válida, mas dá pau ANTES de chamar a função. }
int a; func1(a); /* Será que func1() modifica a? Só dá para saber conhecendo suficientemente bem a função, o que nem sempre é possível imediatamente para alguém que esteja lendo o código pela primeira vez. */ func2(&a); /* Também não dá para ter certeza de se func2() modifica a ou não, mas os programadores C e C++ ficariam menos surpresos se esta aqui o modificasse do que se a outra o fizesse. */ inverte_bits(a); /* O nome da função sugere alteração, logo a chance de surpresa é menor. */
void f_ri(int &); void f_cri(const int &); void f(){ int i=0; const int ci=1; int &ri=i; // OK. int &ri_ci=ci; // Erro de tipo incompatível (int!=const int). int &ri_lit=5; // Erro: referência não-const para constante literal (rvalue). const int &cri=ci; // OK: referência constante para lvalue constante. const int &cri_i=i; // OK: referência constante para lvalue não-const. const int &cri_lit=5; // OK: referência constante para rvalue. cri++; // Erro: tentando modificar ref. constante. cri_i++; // Erro: tentando modificar ref. constante (mesmo com original não-const). cri_lit++; // Erro: tentando modificar ref. constante. f_ri(i); // OK. f_ri(ci); // Erro de tipo incompatível. f_ri(5); // Erro: referência não-const para constante literal (rvalue). f_cri(i); // OK: referência constante para lvalue não-const. f_cri(ci); // OK: referência constante para lvalue constante. f_cri(5); // OK: referência constante para rvalue. }
int a; a=5; a++; // pós-incremento ++a; // pré-incremento a+=5; std::cout << a; (a+=4)=2; // Estanho, mas válido: acrescenta 4 a ‘a’, e depois o sobrescreve com 2. int b; b=a*10;
#include <ostream> #include <iostream> class my_int { private: int value; public: // Construtor de construção de tipo com argumento default. my_int(int val=int()): value(val) { } // Construtor de cópia (mostrado apenas para ser completo no exemplo, // esta versão faz o mesmo que faria um construtor de cópia default, // provido automaticamente pelo compilador, caso omitido; se, no entanto, // o tipo fosse mais complexo e envolvesse ponteiros, provavelmente o // construtor default não seria adequado, e possivelmente deveria haver // também um construtor de movimentação de rvalues). my_int(const my_int &other): value(other.value) { } // Operador de atribuição com conversão de tipo (retorna referência, para // ser semanticamente compatível com funcionamento de tipos nativos, pois // a atribuição devolve um lvalue). my_int &operator=(int val){ value=val; return *this; // Referência retornada á ao próprio objeto que está sendo alterado. // Note que eu retorno “*this”: “this” é um ponteiro, “*this” é o objeto apontado, e a // referência é sobre o objeto. } // Se eu tivesse um tipo contendo ponteiros, provavelmente eu teria de definir // duas versões do operador de atribuição: uma para copiar objetos do tipo my_int // que fossem lvalues, e outra para movimentar rvalues (como objetos temporários). // Operador de pré-incremento devolve lvalue, logo tem de retornar referência. my_int &operator++(){ ++value; return *this; } // Operador de pós-incremento devolve um rvalue, logo devolve uma cópia. my_int operator++(int){ return value++; // Chama implicitamente construtor de conversão de tipo com // valor de ‘value’ antes do incremento, e retorna o objeto // temporário construído. } // O operador para escrever um my_int num stream de saída tem como // primeiro operando um objeto de outro tipo, logo a função operadora // tem de ser defina fora da classe. Fazê-la friend da classe, no entanto, // permite que essa função eventualmente tenha acesso a membros // internos do objeto my_int. friend std::ostream &operator<<(std::ostream &, const my_int &); // Declara forma da função friend. // Operador de atribuição com soma também devolve lvalue, logo tem de // retornar referência. Note que eu forneço apenas uma versão que recebe // outro operando do tipo my_int (por referência constante). Como existe // conversão implícita de int para my_int (via construtor de conversão de // tipo), isso é suficiente para funcionar o equivalente ao exemplo de “a+=4” // mostrado acima. my_int &operator+=(const my_int &other){ value+=other.value; return *this; } // Operador de multiplicação simples retorna rvalue, logo retorna apenas // uma cópia de valor. my_int operator*(const my_int &other){ return value*other.value; // Usa implicitamente construtor de conversão de tipo // e devolve objeto temporário construído. // Operador de conversão de tipo inverso: produz dado de outro tipo a partir // de objeto. Note que o tipo retornado não vem antes da palavra “operator”, // mas é caracterizado pela própria operação. E tem de retornar rvalue. operator int(){ return value; } }; // Função que faz a saída do dado my_int. Como ela tem a mesma assinatura // da que foi declarada como friend de my_int, então pode fazer acesso a dados // privados da classe. Como o objeto os é modificado pela operação de escrita, // a referência a ele não pode ser constante. Já o objeto que vai ser escrito não // será modificado, logo pode -- e deve! -- ser uma referência constante. std::ostream &operator(std::ostream &os, const my_int &mi){ return os << my.value; } int main(){ my_int a; a=5; a++; // pós-incremento ++a; // pré-incremento a+=5; std::cout << a; (a+=4)=2; // Estanho, mas válido: acrescenta 4 a ‘a’, e depois o sobrescreve com 2. int b; b=a*10; }
Enviado em 30/09/2016 - 10:50h
Modifiquei a postagem anterior, pois ela estava incompleta (parei de responder por causa do sono, já na madrugada de ontem). Acho que agora ela trata de todos os pontos levantados na pergunta original.Enviado em 30/09/2016 - 18:39h
Enviado em 01/10/2016 - 09:45h
int a=0; ((((a-=0)/=1)+=2)*=3)=4; // No fim das contas, a=4, mas antes ele foi triplicado, // e antes disso acrescido de 2, e antes dividido por 1 (neutro) e diminuído de zero (neutro).
int a; a*2=4; // Isto não é uma equação que faz a=2, mas um erro de programação // em C++, pois “a*2” não é uma expressão que pode receber um valor.
tux-gpt - Assistente de IA para o Terminal
Instalação e configuração do Chrony
Programa IRPF - Guia de Instalação e Resolução de alguns Problemas
Instalando o Team Viewer no Debian Trixie - problema no Policykit
O Que Fazer Após Instalar Ubuntu 25.04
O Que Fazer Após Instalar Fedora 42
Debian 12 -- Errata - Correções de segurança
Instalando o Pi-Hole versão v5.18.4 depois do lançamento da versão v6.0
Linux iniciando sem interface gráfica (13)
Não consigo acessar servidores a partir da LAN (0)
Pra quem contribui com artigos e dicas (7)
Alguém poderia me ajudar a escolher peças pra montar um desktop? (27)