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

Alocação dinâmica de funçôes em C++


Castro

Pergunta

:wacko:

Considere o código genérico abaixo:

Minhaclasse
  {
   
  int x,y,
   
  public:
              int soma ( int a, int b); // função membro 
  }
   
  float dividir ( float divideno, float divisor) // função não membro
   
  int main()
   
  {
   
    int *p1, *p2;
   
  p=new soma();
  p2=new dividir();
   
  return;
  }
1- Se eu quiser alocar funções individualmente na memória, é possível fazer como acima ? caso seja, qual seria a vantagem ? Pergunto isto, porque exixitem as chamadas funções membro e as não membro. elas são alocadas da mesma forma ? 2- Quando faço
Minhaclasse *p = new Minhaclasse();

a-Ao fazer isto, estou alocando dinâmicamente todas as funções da classe, ?

b-Minhaclasse() não seria o construtor default ?

c- Na classe Minhaclasse, temos variáveis ou atributos, tais como:x, comoalocar variáveis em C++ sem usar as funções malloc() e free de C ?

Obrigado

Link para o comentário
Compartilhar em outros sites

Posts Recomendados

  • 0

Embora o seu código não esteja correto, acredito ter entendido a sua dúvida.

O que você chama de funções "membro" e "não-membro" são alocadas da mesma forma na memória. Suas variáveis são alocadas na Stack, ou seja, só quando a função for chamada é que ela será alocada na memória.

No geral, a vantagem em utilizar alocação dinâmica de memória é que o processo irá consumir aos poucos a memória, conforme a sua necessidade.

Em C++, se você não cria um construtor, a linguagem interpreta que há um por padrão. No caso, Minhaclasse().

Não compreendi a sua última questão (letra "c").

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

:wacko:

Ok. Então vamos por partes, para podermos iniciar uma conversa proveitosa para mim e para outros que leiam este tópico. Antes de eu exclarecer a letra "c", quais os erros em meu código genérico ?

Minhaclasse
  {
  
  int x,y,
  
  public:
              int soma ( int a, int b); // função membro
  }
  
  float dividir ( float divideno, float divisor) // função não membro
  
  int main()
  
  {
  
    int *p1, *p2;
  
  p=new soma();
  p2=new dividir();
  
  return;
  }

Obrigado

Link para o comentário
Compartilhar em outros sites

  • 0

Após a declaração da variável y deve-se substituir a vírgula pelo ponto e vírgula. 1° Erro.

O *p2 é inteiro , e ele irá receber um valor de ponto flutuante como retorno ? 2° Erro.

Está faltando o ponto e vírgula no final da declaração da função dividir 3° Erro.

eu n testei o código e olhando rapido são esses ae..

Link para o comentário
Compartilhar em outros sites

  • 0

:blush:

Realmente são muitos erros de sintaxe falta de atenção. Vou corrigir o código

Minhaclasse
  {
   
  int x,y;
   
  public:
              int soma ( int a, int b); // função membro 
  }
   
  float dividir ( float divideno, float divisor); // função não membro
   
  int main()
   
  {
   
    int *p1;
    float *p2;
   
  p1=new soma();
  p2=new dividir();
   
  return;
  }
mas vamos por partes, foi dito que:
O que você chama de funções "membro" e "não-membro" são alocadas da mesma forma na memória. Suas variáveis são alocadas na Stack, ou seja, só quando a função for chamada é que ela será alocada na memória.
Ok, entendi, que:
int soma ( int a, int b); // função membro
float dividir ( float divideno, float divisor); // função não membro
São apenas definições, assim como os protótipos de C. Para usa-las teria que declara-las como abaixo.
Minhaclasse::float dividir ( float divideno, float divisor);
 // função não membro
{
   corpo....
}
fora de main() e da classe. mas a citação não explica sintaticamente como se aloca memória para tipos base de C++, como o atributo ou variável x do código genérico. Esta é a dúvida da letra "c" Outro ponto que não foi discutido, se eu resolver fizer:
Minhaclasse *p = new Minhaclasse();

O quê está sendo alocado ?

Obrigado

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

  • 0

Seu código continua errado.

Amigo, tente compilá-lo.

Para ver o que é alocado, utilize o código abaixo, teste-o e faça análises.

MinhaClasse m;
    MinhaClasse *p = new MinhaClasse();
    
    cout << "Tamanho da classe: " << sizeof(m) << endl;
    cout << "Tamanho do ponteiro: " << sizeof(p) << endl;

Link para o comentário
Compartilhar em outros sites

  • 0

:(

Ok. Realmente continua errado. Fiz a seguinte modificação:

#include <iostream>
using namespace std;
class Minhaclasse
  {
  
  int x,y;
  
  public:
        int soma ( int a, int b); // função membro
  }
  
  float dividir ( float divideno, float divisor); // função não membro
  
  int main()
  
  {
  
    int *p1;
    float *p2;
  
  p1=new soma();
  p2=new dividir();
  
  MinhaClasse m;
  MinhaClasse *p = new MinhaClasse();
    
    cout << "Tamanho da classe: " << sizeof(m) << endl;
    cout << "Tamanho do ponteiro: " << sizeof(p) << endl;
  
  return 0;
  }
Compilei, e deu vários erros. O quê me chamou mais a atenção, foi o fato do erro cair na linha:
float dividir ( float divideno, float divisor); // função não membro
Escrever está linha, não é a mesma coisa que definir o protótico da função em C ? não deveria funcionar em C++ ? O que está, ainda, errado ? erros
12 D:\Sobre_C++\TestC++\alocando-func.cpp new types may not be defined in a return type 12 D:\Sobre_C++\TestC++\alocando-func.cpp two or more data types in declaration of `dividir' D:\Sobre_C++\TestC++\alocando-func.cpp In function `int main()': 21 D:\Sobre_C++\TestC++\alocando-func.cpp `soma' has not been declared 22 D:\Sobre_C++\TestC++\alocando-func.cpp `dividir' is not a type 24 D:\Sobre_C++\TestC++\alocando-func.cpp `MinhaClasse' undeclared (first use this function) (Each undeclared identifier is reported only once for each function it appears in.) 24 D:\Sobre_C++\TestC++\alocando-func.cpp expected `;' before "m" 25 D:\Sobre_C++\TestC++\alocando-func.cpp `p' undeclared (first use this function) 25 D:\Sobre_C++\TestC++\alocando-func.cpp `MinhaClasse' has not been declared 27 D:\Sobre_C++\TestC++\alocando-func.cpp `m' undeclared (first use this function) 30 D:\Sobre_C++\TestC++\alocando-func.cpp return-statement with no value, in function returning 'int'
Como soma pode estar mau definida, se defini o tipo de retorno e os parâmetros ? Qual deve ser o tipo do ponteiro p para usar na linha
MinhaClasse *p = new MinhaClasse();

Obrigado

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

  • 0

Você definiu a classe como "Minhaclasse" e está tentando utilizar a classe (não existente) "MinhaClasse".

Outra coisa, você está tentando alocar funções. (?)

int *p1;
    float *p2;
  
  p1=new soma();
  p2=new dividir();
Isto não é possível. Se você quiser retornar o valor, você primeiro aloca um int/float na variável e depois atribui o que é retornado da função ao apontado. Exemplo:
int *p1;
float *p2;

p1 = new int;
p2 = new float;

*p1 = soma(1, 5); /* óbvio que isso não é possível, já que a função é um membro da "Minhaclasse" */
*p2 = dividir(10, 2); /* isto é possível, e deveria retornar 5.0f */

Abraços.

Link para o comentário
Compartilhar em outros sites

  • 0

Vamos tirar as dúvidas uma de cada vez.

1) Alocação de memória é exclusivamente para dados. Uma função não pode ser alocada. Ela não ocupa memória propriamente mas sim o código dela. Não importa quantas vezes ela é chamada, não usará mais memória para isso...

2) Função membro é uma função que pertence a uma classe e portanto somente instâncias da classe ou derivadas podem acessá-la.

3) No seu código já está a resposta para o item c. os operadores new e delete são usados no lugar de malloc e free, respectivamente.

4) o comando new aloca memória no tamanho do tipo solicitado. assim o new precisa receber um tipo e não o retorno de uma função. Assim o correto seria como foi citado pelo Durub.

5) Como também foi dito, cuidado pois existe diferenciação entre maiúsculas e minúsculas em linguagem C/C++.

6) A linha que ocorreu o erro nem sempre é onde o problema está mas sim onde ele apareceu. Veja o código:

void loop(void)
{
   for(i=0; i<10; i++) {
      if(i == 0) {
         printf("Primeira passagem\n");

      printf("Estou em %d\n", i);
   }
   printf("saindo...\n");
}

int soma(int a, int b)
{
   return a+b;
}
No código acima o if ficou sem a chave de fechamento. Nesse caso o erro vai acontecer na linha que a função soma é declarada mas a função não tem nenhum erro. O compilador apenas achou que a outra função não tinha terminado! Assim o compilador pensou que você criou uma função antes de terminar a outra. Ou seja: nem a linha nem a mensagem de erro indicam o problema, você terá que analisar o código para saber o que aconteceu. 7) A declaração:
Minhaclasse::float dividir ( float divideno, float divisor);
// função não membro
{
   corpo....
}
está incorreta. O operador de escopo :: indica a quem a função pertence e portanto deve estar antes do nome da função e não do tipo. Além do mais não pode ter o ; no final pois não é o protótipo da função mas sim a função propriamente:
float Minhaclasse::dividir ( float divideno, float divisor)
// função não membro
{
   corpo....
}
Mas se dividir não é membro então ela tem que ser declarada sem o operador de escopo:
float dividir ( float divideno, float divisor)
// função não membro
{
   corpo....
}

Acho que é isso, qualquer dúvida é só falar...

Link para o comentário
Compartilhar em outros sites

  • 0

:blush:

Adimito que que estou com dificuldade. Vou postar o código, com pequena mudança.

#include <iostream>
using namespace std;
class Minhaclasse
  {
  
  int x,y;
  
  public:
        int soma ( int a, int B); // função membro
  }
  
  float dividir ( float divideno, float divisor); // função não membro
  
  int main()
  {
  
    int *p1;
    float *p2;

    p1 = new int;
    p2 = new float;

  /*Se você quiser retornar o valor, você primeiro aloca um int/float
 na variável e depois atribui o que é retornado da função ao apontado.*/
   
  p1=new soma();
  p2=new dividir();
  
  Minhaclasse m;
  Minhaclasse *p = new Minhaclasse();
    
    cout << "Tamanho da classe: " << sizeof(m) << endl;
    cout << "Tamanho do ponteiro: " << sizeof(p) << endl;
  
  return 0;
  }
Erros:
12 D:\Sobre_C++\TestC++\alocando-func.cpp new types may not be defined in a return type 12 D:\Sobre_C++\TestC++\alocando-func.cpp two or more data types in declaration of `dividir' D:\Sobre_C++\TestC++\alocando-func.cpp In function `int main()': 25 D:\Sobre_C++\TestC++\alocando-func.cpp `soma' has not been declared 26 D:\Sobre_C++\TestC++\alocando-func.cpp `dividir' is not a type
8- Se só posso alocar o valor de retorno na função e NÂO a função em si, o que está sendo feito na linha:
Minhaclasse *p = new Minhaclasse();

Sei que a variável "p" não foi declarada, dai já um erro, mas como não entendo o que a citada linha faz.. Me parece que se trata de alguma oprtação co construtor. não tenho certeza.

9-por fim não estou entendendo o porquê doos erros apontados. Exemplo: Como "dividir" pode não ter tipo, se eu defini no protótipo ?

Obrigado

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

  • 0

Prezado Castro, estude!

Você não pode fazer isto:

p1=new soma();
p2=new dividir();
E por quê? Porque soma e dividir não são tipos, mas funções. Você pode, sim, fazer isto:
MinhaClasse *classe = new MinhaClasse();
int soma = classe->soma(10, 20);
cout << "Soma: " << soma << endl;

Link para o comentário
Compartilhar em outros sites

  • 0

Esse aqui ta correto

#include <iostream>
using namespace std;
class Minhaclasse
  {

  int x,y;

  public:
        int soma ( int a, int B); // função membro
  };

  float dividir ( float dividendo, float divisor); // função não membro

  int main()
  {


  Minhaclasse a;
  Minhaclasse b;
  Minhaclasse *p = 0;
    Minhaclasse *z = new Minhaclasse();

    p= &a;
    cout << "End class z " << &z << endl;
    cout << "Ponteiro class z " << z << endl;
    cout << "Endereco  da classe a: " << &a << endl;
    cout << "Endereco  do ponteiro: " << &p << endl;
    cout << "Ponteiro aponta para  : " << p << endl;
    cout << "Endereco  da classe b: " << &b << endl;
    p = &b;
    cout << "Endereco  aponta para : " << &p << endl;

    p=NULL;
    delete z;
    z = NULL;
    cout << "Endereco  do ponteiro p : " << p << endl;
    cout << "Endereco do ponteiro z : " << z << endl;
  return 0;
  }

int Minhaclasse::soma(int a , int b)
{
return a+b;
}

  float dividir ( float dividendo, float divisor) {
return dividendo / divisor;
}

Lembrando que é obrigatorio desalocar a memoria que não sera usada , e setar todos os ponteiros referente a ela para NULL

Agora sim voce vai entender de uma vez o que é ponteiro ;]

Link para o comentário
Compartilhar em outros sites

  • 0

:D

OK,

10-Foi dito que:

Você não pode fazer isto:

p1=new soma();

p2=new dividir();

E por quê? Porque soma e dividir não são tipos, mas funções.

Então volto a questionar, o que é MinhaClasse() após a palavra new, na linha

MinhaClasse *classe = new MinhaClasse();
Eu cheguei a pensar que esta linha estivesse alocando memória para um construtor. No livro C++ guia para iniciantes de Hebert Schildt, alocação dinâmica é visto de forma muito breve, ponteiros praticamente não é comentado. Acho até, que o autor para este tema recomenda a leitura de seu livro “C completo e total” o que complicaria um pouco, pois a abordagem é diferente. Visto que não se considera boa prática de programação usar malloc() e free() com C++ 11- Rodei a nova versão do programa e deu certo. Aproveitei e fiz o acréscimo sugerido para usar a função soma(), deu certo
#include <iostream>
using namespace std;
class Minhaclasse
  {

  int x,y;

  public:
        int soma ( int a, int B); // função membro
  };

  float dividir ( float dividendo, float divisor); // função não membro

  int main()
  {


  Minhaclasse a;
  Minhaclasse b;
  Minhaclasse *p = 0;
  Minhaclasse *z = new Minhaclasse();
  
  int soma = z->soma(10, 20);

    p= &a;
    cout << "End class z " << &z << endl;
    cout << "Ponteiro class z " << z << endl;
    cout << "Endereco  da classe a: " << &a << endl;
    cout << "Endereco  do ponteiro: " << &p << endl;
    cout << "Ponteiro aponta para  : " << p << endl;
    cout << "Endereco  da classe b: " << &b << endl;
    p = &b;
    cout << "Endereco  aponta para : " << &p << endl;
    
    cout << "Soma: " << soma << endl;

    p=NULL;
    delete z;
    z = NULL;
    cout << "Endereco  do ponteiro p : " << p << endl;
    cout << "Endereco do ponteiro z : " << z << endl;
    system ("pause");
  return 0;
  }

int Minhaclasse::soma(int a , int b)
{
return a+b;
}

  float dividir ( float dividendo, float divisor) {
return dividendo / divisor;
}
11-1 Coloquei as linhas
p=NULL;
z = NULL;
após a linha
Minhaclasse *z = new Minhaclasse();

e não percebi diferença na saída do programa, por quê apontar para nulo ao final do programa ao invés do início, se o objetivo ao se fazer isto é impedir que o ponteiro aponte para uma área indevida da memória ? se delete libera memória ocupada por z por que fazez z apontar para nulo depois de z não ocupar memória ?

11-2 NULL não é uma macro de C para fazer com que o ponteiro antes de ser inicializado não aponte para regiões indevidas de memória ? C++ não teria um recurso próprio equivalente, sem recorrer a esta macro ?

Obrigado

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

  • 0

Olá.

Vamos por partes:

Então volto a questionar, o que é MinhaClasse() após a palavra new, na linha

MinhaClasse *classe = new MinhaClasse();
A palavra new é um operador da linguagem. Esse operador serve para alocar memória dinamicamente para um objeto (variável/objeto). Ou seja, eu também posso fazer:
Eu cheguei a pensar que esta linha estivesse alocando memória para um construtor. No livro C++ guia para iniciantes de Hebert Schildt, alocação dinâmica é visto de forma muito breve, ponteiros praticamente não é comentado. Acho até, que o autor para este tema recomenda a leitura de seu livro “C completo e total” o que complicaria um pouco, pois a abordagem é diferente. Visto que não se considera boa prática de programação usar malloc() e free() com C++
Alocar memória é SEMPRE para um objeto e não para um construtor. O próprio Stroustrup (criador do C++) diz que, para C++, é melhor utilizar new em vez de malloc().
// Com um simples número inteiro
int *i;
i = new int;
*i = 10;
Agora, por que fez isto?: ( a )
Minhaclasse *p = 0;
( b )
11-1 Coloquei as linhas
p=NULL;
z = NULL;
após a linha
Minhaclasse *z = new Minhaclasse();

Ora, não tem sentido, neste caso, você apontar para NULL e depois alocar um objeto.

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

  • 0

:)

12- Ok. Entendo que um tipo base, seja um tipo de objeto. Logo int seria um objeto. Você disse:

Alocar memória é SEMPRE para um objeto e não para um construtor. O próprio Stroustrup (criador do C++) diz que, para C++, é melhor utilizar new em vez de malloc().

Certo. Se na linha:

Minhaclasse *z = new Minhaclasse();
Minhaclasse(); não é um construtor, então que tipo de objeto seria ? 13 - Na linha
l= new int[5];
entendo, que estou alocando memória para 5 inteiros. Certo ? posso dizer, que esta linha é a versão de C++ para
l=(int) malloc(10 * sizeof(int);

de C ?

Mas e quando se tratar de vetores ?

Obrigado

Link para o comentário
Compartilhar em outros sites

  • 0

Olá.

Você bem sabe que, em C++, o construtor de um classe não precisa ser declarado pelo programador. Você sabe que o C++ permite que você crie um objeto sem "prototipar" um construtor na classe. Logo, o que você está fazendo é criar um objeto na memória (já que é um ponteiro). Você não está "referenciando" o construtor, mas sim, um objeto, não importando se não há construtor ou se há sobrecarga de construtores. No seu caso, você está criando um objeto do tipo MinhaClasse.

A versão em C para o que você pediu é

int l = (int)malloc(5 * sizeof(int));

E se perceber bem, verá um vetor nada mais é que um ponteiro.

:D

Link para o comentário
Compartilhar em outros sites

  • 0

Bom, a galera ajudou pra caramba, só vou comentar sobre algumas perguntas que acho que não foram bem discutidas.

Minhaclasse *z = new Minhaclasse();
Minhaclasse(); não é um construtor, então que tipo de objeto seria ?
MinhaClasse é o nome da classe para o qual você vai alocar memória. Quando memória é alocada para um objeto, na realidade dados são alocados. Ao objeto só pertencem mesmo os dados, as funções membro são compartilhadas entre os objetos da classe. O compilador passa o ponteiro this implicitamente para a função membro de forma que ela saiba que objeto modificar. Quando você aloca memória para o objeto, o construtor dele é chamado, se você não defininiu um construtor, o construtor padrão "criado" pelo compilador é acionado como já foi mencionado pelo pessoal. Da mesma forma que você inicializa os dados do objeto através de construtores chamados na alocação, você também o pode fazer com tipos fundamentais, ex.:
int *integerPtr = new int(5);
Mas e quando se tratar de vetores ?
Vi num post seu que você entende perfeitamente como alocar memória para vetores com new:
int *vetor = new int[5];
Pra desalocar a memória de um vetor não é coisa de outro mundo, basta acrescentar o operador de subscrito []:
delete [] vetor;

Espero que tenha ajudado.

Abraços.

Link para o comentário
Compartilhar em outros sites

  • 0

:huh:

Realmente você ajudou muito, mas ainda estou "encruado". Então vamos ver o quanto entendi:

Minhaclasse *p = new Minhaclasse();
que quando aloco memória para Minhaclasse(); estou alocando memória para a classe como um todo, da mesma forma que faria com um tipo base, entendi corretamente ? Se meu entendimento é correto, em que situação se aloca memória para uma classe ? Quando aloco memória para uns 50 ints sei como utilizar, mas em que situação se joca toda uma casse para heep ? Perguntei sobre alocação de vetores, porque li sobre "templates" (gabaritos), e fiquei com a idéia fixa, de que em C++ o certo em C++ é usar a classe <vector>. Confirmando então, quando faço:
int *integerPtr = new int(5);
Estou 5 ponteiros para inteiros. Se eu fizer:
int integer = new int(5)
Estarei alocando 5 inteiros na memória Se eu fizer:
int *vetor = new int[5];
Estarei alocando UM vetor de 5 posições que seria o mesmo que:
int vetor = new int[5];

Já que tanto em C como C++ vetores é uma outra forma de tratar ponteiros, pelo menos em C se diz que internamente um vetor é um ponteiro.

Obrigado

Link para o comentário
Compartilhar em outros sites

  • 0
(...)

que quando aloco memória para Minhaclasse(); estou alocando memória para a classe como um todo, da mesma forma que faria com um tipo base, entendi corretamente ? Se meu entendimento é correto, em que situação se aloca memória para uma classe ?

(...)

Quando aloco memória para uns 50 ints sei como utilizar, mas em que situação se joca toda uma casse para heep ?

(...)

Os motivos para alocação dinâmica de objetos são os mesmos para qualquer outro tipo de dados. Um caso interessante pode ser o seguinte, observe o seguinte código:

#include <iostream>
  using std::cout;
  using std::cin;
  using std::endl;
  
  class Numero{
      private:
          int num_;
      public:
          Numero(int num){ set(num); }
          int get(void){ return num_; }
          void set(int num){ num_ = num; }
          void print(void){ cout << get() << endl; }
  };
  
  int main(void){
      Numero *vetor = new Numero[5];
      
      for(int i = 0; i < 5; i++)
          vetor[i].print();
      
      return 0;
  }
Na linha
Numero *vetor = new Numero[5];
resultará em erro, porque como você já deve saber o construtor padrão que o compilador "criava" não pode mais ser chamado porque é definido um construtor que aceita um argumento int. Se você ainda quisesse usar um vetor de objetos e também quisesse seu construtor daquela maneira (com um argumento não-padrão), pra solucionar esse erro você poderia usar alocação diâmica em um vetor de ponteiros pra objetos da classe Numero alí em cima. Mas não precisaria dissso tudo já que você só poderia colocar o único argumento do construtor como um valor padrão, caso nenhum argumento seja passado, como é o caso do código acima. Só estou falando desse exemplo pra você ver como alocação dinâmica pode ser usada pros mais diversos e esquisitos casos, depende do problema e também da lógica do programador.
Perguntei sobre alocação de vetores, porque li sobre "templates" (gabaritos), e fiquei com a idéia fixa, de que em C++ o certo em C++ é usar a classe <vector>.
Esse conselho serve para programadores não experientes ou descuidados em relação a erros comuns que podem ocorrer com vetores (como ultrapassar os limites). Também é bom usar os templates da STL porque eles foram exaustivamente testados pelos desenvolvedores, sendo assim mais confiáveis.
Confirmando então, quando faço:
int *integerPtr = new int(5);
Estou 5 ponteiros para inteiros.
Aqui o correto seria usar colchetes em vez de parênteses. Cuidado.
Se eu fizer:
int integer = new int(5)
Estarei alocando 5 inteiros na memória
O operador new retorna um ponteiro para um inteiro, o lvalue em questão é um inteiro, deveria ser um ponteiro para inteiro. Repito, se sua intenção for alocar vários elementos contínuos, um vetor, use colchetes e não parenteses. Os parênteses são usados para inicialização, então:
int *inteiro = new int(4);
Alocaria um inteiro no heap, inicializaria a posição de memória referente ao inteiro como o valor 4.
Se eu fizer:
int *vetor = new int[5];
Estarei alocando UM vetor de 5 posições
Aqui sim está certo, mas....
que seria o mesmo que:
int vetor = new int[5];
...isso que você afirmou está errado, o lvalue é um inteiro, deveria ser um ponteiro pra inteiro. Cuidado!
Já que tanto em C como C++ vetores é uma outra forma de tratar ponteiros, pelo menos em C se diz que internamente um vetor é um ponteiro.
O que se diz é que o nome do vetor é um ponteiro constante para o primeiro elemento do vetor. EDIT: Esqueci de mencionar uma outra coisa: o c++ fornece dois métodos pra verificar se a alocação foi bem sucedida: Primeiro: se new falhar, lança uma exceção bad_alloc que se não for capturada e manipulada, terminará o programa imediatamente. Segundo: o segundo método pode ser atingido utilizando-se de um objeto especial definido no header <new> e o fornecendo para new como abaixo:
int *vetor = new (nothrow) int[5];
if(!vetor){
  cerr << "Erro ao alocar memória" << endl; // ou qualquer outra atitude
}

Sendo assim, em vez de laçar a exceção, new retorna um ponteiro NULL, como ocorria no C, com a maioria das funções funções.

Espero que tenha lhe ajudado,

Abraços.

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

  • 0

:rolleyes:

Ok.

14- Vamos confirmar para ver se entendi corretamente: Se eu quiser alocar um vetor de 5 elementos a partir de um construtor (alocar dinamicamente um construtor com vetor), como você disse: terei que criar um construtor com argumento default.

Numero(int num=1){ set(num); }
Neste caso todos os elementos do vetor serão 1 que faz concluir que um construtor com vetor deve ser alocado dinamicamente como um ponteiro, como abaixo :
Numero *vetor = new Numero[5];
Logo escrever
Numero vetor = new Numero[5];
É um erro. 15 – Fiz o seguinte teste, mudei a linha para:
Numero *vetor = new Numero;
E na saída do programa mostrou valores como:
1 0 131074 524741 4011977
imagino que seja lixo. Minha idéia era fazer
Numero vetor = new Numero;
E troquei a linha
// vetor[i].print();
por:
vetor.print();
vetor aqui seria a penas um nome, para alocar um construtor sem vetor, mas deu os erros:
C:\Documents and Settings\joubert\Meus documentos\teste.cpp In function `int main()': 17 C:\Documents and Settings\joubert\Meus documentos\teste.cpp invalid conversion from `Numero*' to `int' 17 C:\Documents and Settings\joubert\Meus documentos\teste.cpp initializing argument 1 of `Numero::Numero(int)'
16 – Retornei o programa para o original, e fiz a seguinte mudança no construtor:
Numero(const int num=1){ set(num); }
Ao definir num como argumento constante, o que estou fazendo de prático ? os resultados são os mesmos.do item 14, ou seja, 1. 17 – Se entendi corretamente ao fazer
int *integerPtr = new int(5);
Estou alocando memória para um ponteiro de inteiro e inicializando com valor 5. Correto ? 18- Confirmando, sei que nas linhas i
nt *p;
p= new int;
estou alocando um ponteiro para inteiro, qual é o equivalente da linha
int *p;
p=(*int) malloc(11* sizeof(int));

onde aloco 11 posições de memória para o tipo inteiro usando new de C++ ?

Obrigado

Link para o comentário
Compartilhar em outros sites

  • 0

Vamos com calma, hehehe. São muitas perguntas pra um simples tópico. =]

Só queria te dizer que a maioria do que eu falei já presumia que você soubesse um pouco de POO. É importante que você não se resuma a esse tópico pra estudar o que estamos discutindo. Pesquise um pouco, dê uma lida nuns livros.

14- Vamos confirmar para ver se entendi corretamente: Se eu quiser alocar um vetor de 5 elementos a partir de um construtor (alocar dinamicamente um construtor com vetor), como você disse: terei que criar um construtor com argumento default.

Numero(int num=1){ set(num); }
Neste caso todos os elementos do vetor serão 1
Só se você não passar nenhum argumento pro construtor em questão.
que faz concluir que um construtor com vetor deve ser alocado dinamicamente como um ponteiro, como abaixo :
Numero *vetor = new Numero[5];
Calma, você está confundindo as coisas. O que está sendo alocado é um objeto da classe especificada (especificamente só os seus dados). O construtor é uma função-membro da classe. O que é alocado é o objeto por inteiro.
Logo escrever
Numero vetor = new Numero[5];
É um erro.
Sim.
16 – Retornei o programa para o original, e fiz a seguinte mudança no construtor:
Numero(const int num=1){ 
   set(num); 
}
Ao definir num como argumento constante, o que estou fazendo de prático ? os resultados são os mesmos.do item 14, ou seja, 1.
Na verdade a declaração de um parâmetro "const int num" é sem sentido. O modificador const denota que a variável será constante, ou seja, não poderá ser modificada. Não é necessário pois do jeito que foi declarado vai ser passado por valor, ou seja, o valor da fonte(variável) fornecida na chamada da função é copiado para a variável de parâmetro, o que já impede que a variável original seja modificada pela função.
17 – Se entendi corretamente ao fazer
int *integerPtr = new int(5);
Estou alocando memória para um ponteiro de inteiro e inicializando com valor 5. Correto ?
Mais precisamente: "Estou alocando memória para um inteiro, retornando o endereço desse inteiro alocado na memória para integerPtr e inicializando esse endereço com o valor 5".
qual é o equivalente da linha
int *p;
p=(*int) malloc(11* sizeof(int));
onde aloco 11 posições de memória para o tipo inteiro usando new de C++ ?
Foi o que você fez aqui:
que faz concluir que um construtor com vetor deve ser alocado dinamicamente como um ponteiro, como abaixo :
Numero *vetor = new Numero[5];

Sugiro que você estude um pouco mais sobre orientação a objetos e C++, nos primeiros posts eu supus que você soubesse o básico de POO e acho que isso foi um erro meu. Espero que você tenha compreendido. Continue estudando. Espero ter ajudado.

Abraços.

Link para o comentário
Compartilhar em outros sites

  • 0

:)

20- Foi bom você citar a questão da literatura.. Como disse em poste acima, li o livro “C++ guia para iniciantes” do Hebert Schildt. Mas quando chega em alocação dinâmica e ponteiros, é muito fraco. Eu tentei ler algum material da Internet, mas é muito tosco.

Fui ver o livro do Dentel, “programando em C++”, mas apesar de ser considerado bom, achei muito caro. Ouvi falar na “Bíblia do C/C++”, mas não tenho nenhuma referência de crítica sobre ele. Poderiam indicar alguns livros que sejam bons, mas tenham valor intermediários ?

21- É verdade. Minha experiência, é com programação procedural e orientada para eventos. Estou penando com POO. Eu tento criar um paralelo entre as metodologias mas...

veja então alguns exemplos: Em sua resposta você disse,

a- que a linha:

numero *vetor = new Numero[5];
é equivalente a linha
int *p;
p=(*int) malloc(11* sizeof(int));
Mas quando vejo algo com índice [indice], para mim é um vetor.
int *p;
não é vetor. Para se ter um vetor de ponteiros, teria de ser, se não me engano:
int *p[5];
ou não ? 22- Fazendo um parêntese, em alocação... No programa do post 13, temos a função não membro:
float dividir ( float dividendo, float divisor) {
return dividendo / divisor;
}
Se temos as funções membro da classe, que permitem derivação, polimorfismo etc. por que criar uma função não membro ? compatibilidade com C ? 23- No código do post 14, tem-se a seguinte linha:
int soma = z->soma(10, 20);
mas sei que posso fazer:
int soma = z.soma(10, 20);

que também dará certo, e mostrará o mesmo resultado. Mas conceitualmente qual a diferença de uma forma e outra ? quando é melhor usar uma ou outra ?

Obrigado,

Link para o comentário
Compartilhar em outros sites

  • 0

Caro Castro, vamos com calma.

Este tópico está muito grande e confuso já. ;)

Vamos ver as equivalências da linguagens C e C++:

Queremos alocar um ponteiro do tipo inteiro que tenha seu valor igual a 5

Em C faríamos:

int *p;
p = (int)malloc(sizeof(int));
*p = 5;
E em C++:
int *p;
p = new int(5);
Queremos um ponteiro do tipo inteiro com um espaço de 5 posições na memória Em C faríamos:
int *p;
p = (int)malloc(5*sizeof(int));
E em C++:
int *p;
p = new int[5];

Lembrete: Um vetor nada mais é que um ponteiro. E uma matriz nada mais é que um ponteiro de ponteiro. ;)

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

  • 0

:rolleyes:

Você disse:

Queremos um ponteiro do tipo inteiro com um espaço de 5 posições na memória

int *p;

p = (int)malloc(5*sizeof(int))

Lembrete: Um vetor nada mais é que um ponteiro. E uma matriz nada mais é que um ponteiro de ponteiro

Correto. Lendo sua frase de outra forma: se está alocando um espacço para 5 posições contínuas de memoria para um ponteiro de inteiro, A questão é que olhanho desta forma pode-se visualizar os 5 espaços de memória como sendo ocumados por cinco variáveis inteiras distintas, independente de serem um vetor. Entende a minha confusão agora ? a sintaxe de C permite esta visão. Agora veja o programa abaixo

// Alocar array
#include <iostream>
#include <new>
using namespace std;

int main()
{
    int *p,i;
    try {
         p=new int [10]; // aloque um array de númro inteiro
         
         } catch (bad_alloc xa) {// fique atento a uma falha de alocação
        cout << "Alocação falhou\n";
        return 1;
         }
         
         for (i=0; i<10; i++)
         p[i]=i;
         
         for (i=0; i<10; i++)
         cout << p[i] << " ";
         
         
         delete [] p; /* Limpa a memória alocada pelo array*/
         
         system ("pause");
         return 0;
Já na sintaxe de C++ eu entendo que p é um vetor com 10 posições alocado dinamicamene, ou seja, tenho uma só variável que aloca um conjunto de dados contínuos. Pelo que entendi, o que faz da linha:
p=new int [10];
um vetor é a linha
delete [] p;
Se eu fizesse:
delete  p;
Então
p=new int [10];

Teria a interpretação que dei para sintaxe de C. Espero ter conseguido explicar minha dúvida ou confusão que estou fazendo.

Se puder comentar os livros que citei ou indicar algum...

Obrigado

Editado por Castro
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
      152k
    • Posts
      651,8k
×
×
  • Criar Novo...