Ir para conteúdo
Fórum Script Brasil
  • 0

(Resolvido) Dúvidas simples


mtp

Pergunta

Pessoal,

Estou com umas dúvidas bem básicas em C/C++.

Estou usando um código em C++, baseado em classes. Criei um console application no visual studio, e adicionei uma função para chamar os métodos dessa classe.

(1) Por exemplo, quero chamar o método "processar(...)", da classe "CProcesso". Como sei que devo usar a declaração (a) ou (b)?

(a)

CProcesso vprocesso;

vprocesso.processar(...);

(b)

CProcesso *vprocesso = NEW CProcesso();

vprocesso->processar(...);

(2) Outra dúvida, por que usar o "malloc", quando se pode usar o "new"?

Agradeço a atenção!

Link para o comentário
Compartilhar em outros sites

7 respostass a esta questão

Posts Recomendados

  • 0

bom, ultimamente tenho estudao c por conta propria, e as repostas q eu vo dar são baseadas nas conclusoes q cheguei pelo q já vi por ai, não são baseadas em nenhum conceito, nd e pode não tar 100% correto, mas acho q seria mais ou menos isso:

(1) Por exemplo, quero chamar o método "processar(...)", da classe "CProcesso". Como sei que devo usar a declaração (a) ou (B)?

bom, no primero caso você ta instanciando o objeto normalmente. agora no segundo você ta criando um ponteiro pra ele. isso significa q você ta declarando uma regiao qualquer na memoria, e com o new você aloca esse espaco com um objeto da classe CProcesso.

no fundo acaba dando no mesmo, mas usando o ponteiro você tem um acesso maior. tipo quero dizer assim, se você declara o objeto (como no exemplo a) dentro de uma funcao ou um bloco de comando qualquer, no final do bloco (quando ele chegar em }) o objeto é destruido e td q tinha nele é perdido.

agora se você alocar a regiao na memoria, mesmo q a funcao termine, o espaco continua alocado ate você chamar o delete. o endereco no pontero (a variavel vprocesso) realmente é perdido quando termina a funcao, mas na verdade o o espaco na memoria continua la ocupado. e ai se você armazenar esse endereco (se você der um jeito de passa-lo pra fora da funcao) você pode continuar utilizando.

uma vantagem disso por exemplo são funcoes q retornam string. as funcoes q retornam string tem ser do tipo ponteiro de char, ou seja, o resultadao dela retornara o endereco da memoria onde esta o resultado e não o resultado em si. mas acontece q assim q a funcao termina, o espaco dela é liberado (as variaveis internas dela, inclusive os ponteros são destruidos). então, as vezes é meio chato mexer com essas funcoes, porque por exemplo você não consegue dar printf direto nela. mas se você alocar algum espaco com o new, você tem mais facilidade.

outra coisa tb sobre declara com pontero é q apesar de q exige mais trabalho pra se usar, é q o acesso a ele é muito mais rapido. porque se você acessa o objeto, o objeto aponta o endereco e ai sim o endereo é acessado. se você acessa o pontero ele vai direto no endereco.

no fundo a diferenca parece pequena, mas em aplicacoes gds q tem gde processamento de dados, isso faz diferenca e imagino q se costume fazer um uso bem gde de pontero nesses casos.

(2) Outra dúvida, por que usar o "malloc", quando se pode usar o "new"?

a se eu não me engando q o malloc era uma funcao q existia em c pra realocar memoria e ai quando criaram o c++ inventaram o new pra dar mais facilidade no uso de objetos.

agora acontece q com o malloc você consegue especificar certinho o espaco q você quer. tipo, você pode alocar um espaco maior do q o necessario. qual o objetivo disso?? o mais comum é pra se alocar memoria pra um array. se eu quero um array de 10 posicoes, aloco o espaco pra 10 inteiros, ou seja, sou q escolho o espaco q quero alocar, enquanto q com o new, ate onde sei, só posso alocar um tamanho fixo, de acordo com o tipo q eu passar.

Link para o comentário
Compartilhar em outros sites

  • 0
bom, ultimamente tenho estudao c por conta propria, e as repostas q eu vo dar são baseadas nas conclusoes q cheguei pelo q já vi por ai, não são baseadas em nenhum conceito, nd e pode não tar 100% correto, mas acho q seria mais ou menos isso:

(1) Por exemplo, quero chamar o método "processar(...)", da classe "CProcesso". Como sei que devo usar a declaração (a) ou (B)?

bom, no primero caso você ta instanciando o objeto normalmente. agora no segundo você ta criando um ponteiro pra ele. isso significa q você ta declarando uma regiao qualquer na memoria, e com o new você aloca esse espaco com um objeto da classe CProcesso.

no fundo acaba dando no mesmo, mas usando o ponteiro você tem um acesso maior. tipo quero dizer assim, se você declara o objeto (como no exemplo a) dentro de uma funcao ou um bloco de comando qualquer, no final do bloco (quando ele chegar em }) o objeto é destruido e td q tinha nele é perdido.

agora se você alocar a regiao na memoria, mesmo q a funcao termine, o espaco continua alocado ate você chamar o delete. o endereco no pontero (a variavel vprocesso) realmente é perdido quando termina a funcao, mas na verdade o o espaco na memoria continua la ocupado. e ai se você armazenar esse endereco (se você der um jeito de passa-lo pra fora da funcao) você pode continuar utilizando.

uma vantagem disso por exemplo são funcoes q retornam string. as funcoes q retornam string tem ser do tipo ponteiro de char, ou seja, o resultadao dela retornara o endereco da memoria onde esta o resultado e não o resultado em si. mas acontece q assim q a funcao termina, o espaco dela é liberado (as variaveis internas dela, inclusive os ponteros são destruidos). então, as vezes é meio chato mexer com essas funcoes, porque por exemplo você não consegue dar printf direto nela. mas se você alocar algum espaco com o new, você tem mais facilidade.

outra coisa tb sobre declara com pontero é q apesar de q exige mais trabalho pra se usar, é q o acesso a ele é muito mais rapido. porque se você acessa o objeto, o objeto aponta o endereco e ai sim o endereo é acessado. se você acessa o pontero ele vai direto no endereco.

no fundo a diferenca parece pequena, mas em aplicacoes gds q tem gde processamento de dados, isso faz diferenca e imagino q se costume fazer um uso bem gde de pontero nesses casos.

No primeiro caso você está alocando de maneira estática. A classe é alocada na STACK do escopo atual. No segundo você está declarando um ponteiro, e atribuindo a ele um endereço de memória alocado dinâmicamente(na HEAP, área fixa de memória).

Ao alocar dinâmicamente, ganhamos dinamismo no programa e executaveis menores. Porém, PRECISAMOS ter alguns cuidados a mais. Se a função termina e existem objetos dinamicamente alocados, eles permanecem na memória. Quando isso acontece, PRECISAMOS retornar um ponteiro para que a função chamadora consiga de alguma forma desalocar(delete) o objeto quando este já for desnecessário. Caso um ponteiro não seja retornado, o ponteiro ainda é alocado na STACK(o ponteiro, e não a área para onde ele aponta), e ele será perdido, ocasionando um memory leak.

Por isso, utilize a alocação dinâmica com responsabilidade.

Quanto as strings, que em C eram simples arrays de caracteres, elas ganharam um tratamento orientado a objetos na STL:

std::string string1("hahaha");
Prefira sempre utilizar a string da STL. Se precisar uma string de widechar em vez de char, utilize:
std::basic_string<wchar> string2;
(2) Outra dúvida, por que usar o "malloc", quando se pode usar o "new"?
a se eu não me engando q o malloc era uma funcao q existia em c pra realocar memoria e ai quando criaram o c++ inventaram o new pra dar mais facilidade no uso de objetos. agora acontece q com o malloc você consegue especificar certinho o espaco q você quer. tipo, você pode alocar um espaco maior do q o necessario. qual o objetivo disso?? o mais comum é pra se alocar memoria pra um array. se eu quero um array de 10 posicoes, aloco o espaco pra 10 inteiros, ou seja, sou q escolho o espaco q quero alocar, enquanto q com o new, ate onde sei, só posso alocar um tamanho fixo, de acordo com o tipo q eu passar.
Não é uma questão de facilidade no uso de objetos. O operador new faz uma alocação dinâmica, como a função malloc, porém ele constrói o objeto na memória(invoca o construtor da classe), ao contrário da função malloc que simplesmente aloca e deixa lixo na região de memória. Em C++ SEMPRE use new e delete em vez de malloc e free. O malloc existe porque em C não existe new/delete, operadores introduzidos no C++. Com o new podemos alocar espaço para um array também:
CProcesso *array = new CProcesso[10];
Apesar disso, o melhor é utilizarmos os containers da STL ao invés de arrays. Eles são mais dinâmicos e flexíveis:
vector<CProcesso> primeiro_vetor;
vector<CProcesso> segundo_vetor(10); //inicializamos com 10 posições

Desta maneira se pode inserir, alterar, remover, procurar, (...) no vetor com muita facilidade.

Link para o comentário
Compartilhar em outros sites

  • 0
Em C++ SEMPRE use new e delete em vez de malloc e free.

porque sempre?? qual o problema do malloc??

e quanto ao realloc??

Prefira sempre utilizar a string da STL. Se precisar uma string de widechar em vez de char, utilize:

std::basic_string<wchar> string2;

o q é widechar?? ate procurei ai no google, mas não encontrei a definicao.

Link para o comentário
Compartilhar em outros sites

  • 0

new e delete possuem menos chances de o usuário errar na chamada e uso.

Se for utilizar realloc, precisa do malloc mesmo, é uma exceção no C++. (Quer dizer, não que não possa usar malloc, mas não é recomendado)

widechar é uma string aonde cada valor tem 2 bytes, ao invés de 1.

Abraços.

Link para o comentário
Compartilhar em outros sites

  • 0
new e delete possuem menos chances de o usuário errar na chamada e uso.

como assim, você diz na hora de chamar?? seria quanto aos parametros do malloc, tipo o tamanho do espaco??

quer dizer q o problema do malloc é somente q o programador pode fazer bestera ao usar??

o widechar seria tipo pra guardar texto em formato unicode ou alguma coisa do tipo??

falou.

Link para o comentário
Compartilhar em outros sites

  • 0

Sim, o new cuida de toda parte "low level" da alocação.

Por exemplo, em C:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    float *p;

   p = (float *) malloc(sizeof(float) * 100); /* Para alocar 100 elementos */

   return 1;
}
Já em C++:
#include <iostream>

int main(void) {
    float *p;

    p = new float[100]; /* O new sabe que float possui 4 bytes */
    delete[] p;

    return 1;
}
Mas não, não é somente isso. Quando a alocação não é válida, ele joga uma exceção (std::bad_alloc) ou chama uma função. (que você escolhe pelo set_new_handler (acho que é do <new>)) Em C:
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    void *address;

    address = malloc(5000);
    if(address == NULL)
        return 1;

    return 0;
}
Em C++:
#include <iostream>
#include <new>

void newHandler(void);

int main(void) {
    int *p;

    std::set_new_handler(newHandler); /* Para usar a exceção, comente esta linha */

    try {
        x = new int[50000];
    } catch(std::bad_alloc) {
        std::cout << "Alocação falhou.";
    }
   
    return 0;
}

void newHandler(void) {
    std::cout << "Alocação falhou.";
}
Ainda, o C++ permite fazer um overload nos operadores new, new[], delete e delete[]. Exemplo:
#include <iostream>

void* operator new(unsigned int bytes);

int main(void) {
    int *x;
    int *y;

    x = new int;
    y = new int;

    return 0;
}

void* operator new(unsigned int bytes) {
    std::cout << "Tentando alocar " << bytes << " bytes."; /* Note que aqui não vai alocar nada, só mostrar essa frase e retornar 0 */
    return (void *) 0;
}

Output:

Tentando alocar 2 bytes.

Tentando alocar 2 bytes.

No geral, é isso.

Abraços.

Editado por Durub
Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...