Nick-us
(usa Slackware)
Enviado em 28/05/2020 - 15:06h
paulo1205 escreveu:
Talvez o que a biblioteca da linguagem oferece seja um pouco menos relevante do que algo que o framework que você utiliza possa trazer. Não sei o weWidgets, que nunca usei, mas o Qt, que eu vou pegar como exemplo, tem uma hierarquia de classes próprias que substituem equivalentes nas bibliotecas padrões do C e do próprio C++. Se você estiver usando Qt, pode ser mais útil usar exclusivamente QString no seu programa, em lugar de std::string , ou QDateTime em lugar de time_t e std::tm e funções relacionadas, porque você vai acabar sendo forçado a usar o tipo do Qt na hora de usar a interface gráfica. Misturar tipos semelhantes no mesmo programa acaba criando um tipo de inchaço e perda de desempenho por causa da necessidade de converter de um tipo para outro tipo funcionalmente equivalente a cada vez que você transfere dados internos para a interface gráfica ou recebe dados da GUI para os seus objetos internos.
Importantíssimo essa informação para mim e para muitas outras pessoas! Pois eu não estava vendo por esse lado! E sempre me incomodou muitas vezes essas criações. Na wxWidgets também existe essas similiridades, que hoje levarei em conta para analise de desempenho, Eu via apenas o mais novo como algo mais pesado, me esqueçendo da transição e comunicação entre eles.
Há quem critique o fato de o Qt não usar mais tipos nativos ou da biblioteca padrão, mas eu compreendo a escolha de projeto feita pelos implementadores do Qt. O Qt é multiplataforma, e tem de funcionar do mesmo modo em todas as plataformas que suporta. No entanto, os compiladores e as bibliotecas que os acompanham têm muitas variações entre sino que tange a certos tipos fundamentais, como wchar_t , que no Windows é de 16 bits e no mundo UNIX e Linux tende a ser sempre de 32 bits. Existem várias outras diferenças como essa, mas essa, sozinha, já tenderia a causar dificuldades de portabilidade em todas as operações com strings . Uma forma supostamente simples de lidar com esse problema seria fazer conversões de tipo cada vez que algum dado interno tivesse de ser apresentado ou que algum valor recebido tivesse de ser armazenado internamente, só que nós já vimos que essas conversões degradam o desempenho, aumentam o tamanho do código e, no fim das contas, não agregam valor nenhum. Então o pessoal do Qt fez algo a princípio anti-intuitivo, que é meio que reinventar a roda (várias rodas, aliás), mas que, no final das contas, melhorava não apenas a portabilidade, mas o próprio desempenho e o tamanho de código por meio da eliminação de conversões, desde que você use exclusivamente (ou tão próximo de exclusivamente quanto possível) os tipos que o Qt lhe apresenta.
Também muito importante sua observação, noto que preciso também controlar o meu nível de crítica, porque acaba sendo comum eu criticar ou não gostar de alguma coisa e obviamente porque não entendi o motivo da existência dela, ou seu objetivo e funcionamento, preciso melhorar isso. Ainda bem que tudo o que me incomoda e que acho errado, costumo perguntar para ter opiniões diferentes das pessoas para que eu entenda se estou pensando correto ou se estou completamente equivocado.
Voltando ao wxWidgets, pareceu-me, pelo que eu li, que ele usa muita coisa da biblioteca padrão do C++, incluindo std::string . Sendo esse o caso, você deve preferir usar os mesmos tipos que ele usa. Caso contrário, você pode acabar provocando operações de conversão de tipos que poderiam ser evitadas, o que aumenta o inchaço e degrada o desempenho, mesmo que seja uma mera conversão de array de caracteres para std::string .
Sim esses seus esclarecimentos acima sobre isso, me ensinaram a ver de outra forma, ainda bem!
Tirando isso, vale sempre o princípio de que não existe almoço grátis. A conveniência sintática do C++ cobra seu preço. Quase sempre esse preço é pago no momento da compilação, não no de execução, o que é ótimo, pois é um preço que o seu usuário não vai pagar.
Boa observação e muito importante, como sou iniciante e ainda não tenho muita experiência em compilação, em como funciona e como são esses resultados, não passou por minha cabeça essa diferença, de verdade eu nunca me preocupei com o tempo de compilação, pq nem cheguei nesse nível ainda, visto que tudo que compilo leva segundos (Programas que eu criei claro, não considerando programas para o Linux de terceiros), minha preocupação sempre é com a execução e consumo de recursos, mesmo claro, não chegando a nada ainda que consuma! Mas sei que no futuro, meus programas podem e obviamente poderão consumir recursos importantes.
Mas existe também um lado de que você, como programador, tem de cuidar: a sintaxe simples pode às vezes esconder uma operação que é custosa. Um exemplo que já foi comentado é a conversão de tipos que pode ocorrer em expressões simples, como ilustra o exemplo abaixo.
void f(const std::string &s){ /* faz alguma coisa com s */ }
int main(){
// Vai provocar um milhão de operações de construção por conversão de tipo, e depois um milhão
// de chamadas a f() com o valor convertido para o objeto temporário, e, por fim, um milhão de
// desconstruções do objeto temporário criado.
for(int i=0; i<1000000; ++i)
f("Paulo");
// Aqui não vai haver conversão de tipo nem desconstrução de objeto dentro do laço
// de repetição: f() vai ser invoca um milhão de vezes usando uma referência para o
// mesmo objeto, construído e desconstruído uma só vez.
const std::string paulo("Paulo");
for(int i=0; i<1000000; ++i)
f(paulo);
}
Amei também essa explicação! O que mostra que preciso estudar ainda mais! pra entender ainda mais as pequenas coisas! Quanto mais aprendo, mais descubro que não sei nada! E esse exemplo ainda me assustou bastante, porque eu julgaria o 1º Exemplo o melhor a se fazer! E pelo visto vou ter que revisar todos os meus conceitos e me esforçar mais para saber diferenciar corretamente o que é Otimizado e o que não é! Aliás, terei que criar inúmeros testes até compreender bem esse conceito. Meu nível ainda é baixo, então eu pensava que escrever é gastar recursos, então eu pensava, se estou declando uma constante, estou gastando 1 recurso e com isso meu programa fica mais pesado. E por falta de conhecimento, não tinha e ainda acho que não tenho capacidade de avaliar o que de verdade gasta ou não recursos conforme o que vc mostrou! O que ao menos agora SEI que é um FATOR importante que terei que aprender! UAU!
Quanto a usar C ou C++, acho que você já perguntou isso outras vezes. Vamos resumir do seguinte modo: se você já tem funções prontas em C, preferencialmente oferecidas em forma de biblioteca, use essas funções do jeito como estão. Se não as tiver prontas, se elas não estiverem em forma de biblioteca e se sua eventual reimplementação em C++ for simples, ou ainda se você perceber que seu uso vai incorrer em perda de desempenho por causa de múltiplas conversões de tipo ou cópia de valores de um lado para o outro, faça-a ou reimplemente-as em C++.
Entendi, mas aqui vai cair no fator acima, tenho que saber reconhecer o que consome e o que não consome!
E note que “fazer em C++” não necessariamente significa que você vai ter de socar tudo dentro de classes (como faz o Java, mesmo para o que não precisaria estar dentro de uma classe). C++ é multiparadigma: se lhe bastarem funções, use funções; se lhe bastarem estruturas que não sejam classes, use estruturas; se tiver de usar classes de tipos concretos, sem polimorfismo, use desse modo; se precisar de polimorfismo, use-o com sabedoria; se lhe ajudar programação genérica, use-a. Seu programa não vai ser mais em C++ ou menos em C++ por causa do paradigma que você escolher (pode sê-lo por outros fatores, especialmente se você usar sintaxe ou construções do C que são expressamente repudiadas em C++, tais como conversão de tipo na forma “(nome_do_tipo)valor_a_ser_convertido ” em vez de construtores de conversão de tipo ou de conversão explícita por meio de static_cast /const_cast /dynamic_cast /reinterpret_cast , ou malloc ()/free () em lugar de new /delete ou new[] /delete[] ).
Interessante, qdo eu compilo em C++ eu gosto de seguir as normas! Acho que depois que aprendi com vc, como compilar, como respeitar o compilador, como respeitar e interpretar seus Warnings. Gosto que esteja tudo bonitinho. A Parte boa de aprender a compilar e vencer os Warnings é que somente assim que podemos quebrar alguma regra! As vezes pego exemplos na Internet, e que para que eu os veja funcionando e analise se irei usar ou aproveitar, para alguns desses exemplos eu abro exceção na compilação para ve-los rapidamente em ação. E ao avaliar, se usarei aquele exemplo, então sim, ele terá que respeitar as regras dos Warnings, então me esforço para consertar o exemplo e colocar ele bonitinho no Padrão que o compilador exige! Não sei porque gostei de fazer assim! No Início eu ficava chateado mesmo com o compilador, mas depois quando aprendi a respeitar as regras dele, aprendi a buscar a solução para que o programa seja aprovado com nota 10.