Ir para o conteúdo
Virtual Void

Duvidas com destrutor

Mensagens Recomendadas

Virtual Void    0
Virtual Void

Boas tenho estes files  que compoem um programa que cria uma base de dados de pessoas.

No entanto gostava de saber como posso fazer para destruir as pessoas, ou seja no fim do programa todas as pessoas serem destruidas e a base de dados ser destruida. neste programa como ele esta actualmente isso nao acontece. as pessoas sao construidas mas nao destruidas. como faço para destruir as pessoas?

Pessoa.hh :

#ifndef PESSOA_H
#define PESSOA_H

class Pessoa 
{
  public:
     Pessoa(char *name, char* num, int age);
     virtual ~Pessoa();
     virtual void write();

  private:
     char *nome;
     char *num_bi;
     int idade;

};

#endif

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Pessoa.cpp :

#include <iostream>
using namespace std;

#include "Pessoa.hh"

Pessoa::Pessoa(char *name, char *num, int age)
{
   nome= new char[strlen(name)+1];
   strcpy(nome,name);
   num_bi= new char[strlen(num)+1];
   strcpy(num_bi,num);
   idade=age;
cout<< "construi uma pessao" << endl;
}

Pessoa::~Pessoa()
{
   delete [] nome;
   delete [] num_bi;
   cout<< "destrui uma pessao" << endl;
}


void Pessoa::write()
{
   cout << "nome: " << nome << " num bi: " << num_bi << " idade: " << idade << endl;
}

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Lista.hh :

#ifndef LISTA_H
#define LISTA_H

#define NUM_MAX_PESSOAS 1000

class Pessoa;

class Lista
{

  public:
     Lista(); 
     virtual bool adicionarP();
     virtual bool removeP(int n);
     virtual void writeList();

  private:
     int numP;
     Pessoa *lista[NUM_MAX_PESSOAS];

};
#endif

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Lista.cpp :

#include <iostream>
using namespace std;

#include "Lista.hh"
#include "Pessoa.hh"


Lista::Lista()
{
  numP=0;
}

bool Lista::adicionarP()  
{
   char name[30], num[20];
   int age;

   if(numP==NUM_MAX_PESSOAS)
   {
      cout << "Lista Cheia!" << endl;
      return false;
   }

   cout<< "Introduza o nome: ";
   cin>> name;
   cout<< "Introduza o bi: ";
   cin>> num;
   cout<< "Introduza a idade: ";
   cin>> age;
  
   lista[numP]=new Pessoa(name,num,age);
   numP++;
   return true;
}
   

bool Lista::removeP(int n)
{

   if(numP==0)
   {
     cout<<endl<<"Erro - A lista ja esta vazia!"<<endl;
     return false;
   }
   else if(n>numP)
   {
     cout<<endl<<"Erro - Pessoa Invalida"<<endl;
     return false;
   }
   else if(n<1 || n>NUM_MAX_PESSOAS)
   {
      cout<<endl<<"Erro - Pessoa Invalida"<<endl;
      return false;
   }
   
   
   for(int i=n-1; i<numP;i++)
     lista[i]=lista[i+1];
   numP--;
   cout<<endl<<"Removido com sucesso"<<endl;
   return true;
}

void Lista::writeList()
{
   
   for(int i=0; i<numP; i++)
      lista[i]->write();
}

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

main.cpp :

#include <iostream>
using namespace std;

#include "Pessoa.hh"
#include "Lista.hh"

int main()
{
  int op,x;

  Lista l1;

  do
  {
    cout<<endl<<" 		Super Base Dados	"<<endl<<endl;
    cout<<"1-Adicionar a base dados"<<endl;
    cout<<"2-Remover base dados"<<endl;
    cout<<"3-Listar base dados"<<endl;
    cout<<"4-Sair"<<endl;
    cout<<"opcao -> ";
    cin>> op;

    switch(op)
    {
      case 1 : l1.adicionarP(); break;
      case 2 : cout<<endl<<"numero: "; cin>>x; l1.removeP(x); break;
      case 3 : l1.writeList(); break;
      case 4 : cout<<endl<< "Programa Terminado! "<<endl; break;
      default : cout<<endl<<"Opcao invalida!!"<<endl;
    }
   }while(op!=4);
  return 0;
}

obrigado pela ajuda

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
wrproject    0
wrproject

class Pessoa

{

  public:

    Pessoa(char *name, char* num, int age);

    virtual~Pessoa();

    virtual void write();

  private:

    char *nome;

    char *num_bi;

    int idade;

};

se reparares, no teu protótipo tens um destrutor do tipo virtual, o que se passa é o seguinte, os destrutores e os construtores, não podem ter nenhum tipo de retorno, nem sequer do tipo void. o código correcto seria:

class Pessoa 
{
  public:
     Pessoa(char *name, char* num, int age);
      ~Pessoa();
     virtual void write();

  private:
     char *nome;
     char *num_bi;
     int idade;

};

tenta fazer isto, pode ser que resulte, espero ter ajudado.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Virtual Void    0
Virtual Void

nao percebest o meu problema... Se eu criar um objecto pessoa no main ele utiliza o destrutor da classe Pessoa e destroi a pessoa que criei. No entanto se eu criar um objecto pessoa atraves da classe Lista ele constroi a pessoa usando o construtor da classe Pessoa mas depois nao destroi o objecto utilizando o destrutor da classe Pessoa.

Quanto à utilizaçao do virtual no destrutor nao esta incorrecto. Alias deve definir-se o destrutor como virtual para que a destruiçao seja realizada segundo a

ligação dinâmica pelo que é invocado o destrutor adequado para assim tirar partido do polimorfismo.

obrigado na mesma

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Virtual Void    0
Virtual Void

sim é provavel. mas eu nao sei como construir esse destrutor. podes ajudar-me? como faço para chamar o destrutor  de Pessoa dentro do da lista? obrigado

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Virtual Void    0
Virtual Void

o array lista? mas assim estaria apenas a apagar os ponteiros e nao o conteudo apontado por eles, que neste caso é cada uma das pessoas

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Virtual Void    0
Virtual Void

entao o destruto fikaria kaulker koisa do genero:

Lista::~Lista()
{
    for(int i=0; i<numP; i++)
         delete *lista[i];
    delete [] lista;
}

ou nem por isso?

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Virtual Void    0
Virtual Void

mas o delete so apaga o ponteiro. nao vai apagar o objectoi para o qual o ponteiro aponta pois nao?

Pk ao fazer isso o destrutor da classe Pessoa nao é executado.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
shumy    17
shumy

O delete apaga o que o ponteiro aponta, o objecto criado.

O destrutor de Pessoa tem de ser chamado, a não ser que me esteja a escapar alguma coisa no teu código, porque o comportamento correcto é esse.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
TheDark    0
TheDark

O que ele disse está correcto. O destrutor não está a ser chamado porque l1 é criada dentro da função main, e como os recursos vão ser libertados automaticamente quando a função main retorna, o compilador não faz a chamada aos destrutores. Experimenta colocar o main.cpp assim:

#include <iostream>
using namespace std;

#include "Pessoa.h"
#include "Lista.h"

int run()
{
  int op,x;

  Lista l1;

  do
  {
    cout<<endl<<" 		Super Base Dados	"<<endl<<endl;
    cout<<"1-Adicionar a base dados"<<endl;
    cout<<"2-Remover base dados"<<endl;
    cout<<"3-Listar base dados"<<endl;
    cout<<"4-Sair"<<endl;
    cout<<"opcao -> ";
    cin>> op;

    switch(op)
    {
      case 1 : l1.adicionarP(); break;
      case 2 : cout<<endl<<"numero: "; cin>>x; l1.removeP(x); break;
      case 3 : l1.writeList(); break;
      case 4 : cout<<endl<< "Programa Terminado! "<<endl; break;
      default : cout<<endl<<"Opcao invalida!!"<<endl;
    }
   }while(op!=4);

  return 0;
}

int main() {
run();
return 0;
}

e vais ver que já são chamados. Não concordo muito com isto, pode causar problemas por exemplo quando num destrutor são libertados recursos do sistema operativo, como handles, mas é o que acontece.

Há aí uma grande confusão com a palavra reservada virtual. Em 1º lugar, virtual não é um tipo, é um modificador. Depois, só faz sentido utilizar métodos virtuais quando a classe que os contém vai ser derivada. O que o virtual faz é o seguinte: tendo as classes A e B:

class A {
int x;
public:
A() {
	x=0;
}

void printx() {
	cout << "x = " << x << endl;
}

virtual ~A() {
	cout << "Sou uma instância de A" << endl;
}
}

class B: public A {
public:
B() {
	x=1;
}

virtual ~B() {
	cout << "Sou uma instância de B" << endl;
}
}

e o seguinte código:

A *p = new A;
p->printx(); //"x = 0"
delete p; // "Sou uma instância de A"
p=new B;
p->printx(); // "x = 1"
delete p; // "Sou uma instância de B"

no 1º delete será chamado o destrutor de A, e no 2º o de B. Se o destrutor de A não fosse virtual, em ambos os deletes seria chamado o destrutor de A.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
merlin3000    0
merlin3000

Mas o compilador não devia chamar o destrutor mesmo estando a lista declarada no main?

int main()
{
  Lista l1;

  Pessoa p1("p1");
  l1.adicionarP("p2");

  return 0;
}

Com este código no main e o destrutor:

Lista::~Lista() {
    cout << "\nA eliminar lista";
    for( int i = 0; i < numP; i++ )
        delete lista[i];
}

Ele chama o destrutor de ambas as pessoas.

Fiz umas alterações ao código mas apenas no construtor da pessoa e no membro adicionarP para poder inserir as pessoas mais facilmente.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora


×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade