Newsgroup: it.comp.lang.c
Titolo: Oggetti e allocazione dinamica della memoria

Il seguente codice è un adattamento di un programma C++...
#include <stdio.h>
#define TAB '\t'
typedef struct tagQ
{
 int back;
 char *data[10];
 void (*JoinQ)(char *ch);
 void (*LeaveQ)(void);
 void (*ShowQ)(void);
 void (*_Q)(void);
}Q;
Q *new__Q(void);
void _Q(void)
{
   Q *a = new__Q();
   a->back = 0;
}
void ShowQ(void)
{
 int x;
 Q *b = new__Q();
 if (b->back == 0)
 {
  printf("Q is empty\n\n");
 }
 else
 {
  for (x = 1; x <= b->back; x++)
  {
   printf(b->data[x],TAB);
  }
  printf("\n\n");
 }
}
void JoinQ(char *ch)
{
 Q *c = new__Q();
 if (c->back < 9)
 {
  c->back++;
  c->data[c->back] = ch;
 }
 else
 printf("Q is full\n");
}
void LeaveQ(void)
{
 int index;
 Q *d = new__Q();
 for (index = 1; index < d->back; index++)
 {
  d->data[index] = d->data[index + 1];
 }
 d->back--;
}
Q *new__Q(void)
{
 Q *result = malloc(sizeof(Q));
    memset(result,0,sizeof(Q));
 result->_Q = _Q;
 result->ShowQ = ShowQ;
 result->JoinQ = JoinQ;
    result->LeaveQ = LeaveQ;
    return result;
}
int main()
{
    Q *One = new__Q();
 One->ShowQ();
 One->JoinQ("Z\t");
 One->ShowQ();
 One->JoinQ("A\t");
 One->ShowQ();
 One->JoinQ("K\t");
 One->ShowQ();
 One->LeaveQ();
 One->ShowQ();
 One->LeaveQ();
 One->ShowQ();
 One->LeaveQ();
 One->ShowQ();
 return(0);
}
L'output corretto dovrebbe essere:
Q is empty
Z
Z A
Z A K
A K
K
Q is empty
ma invece si ottiene
Q is empty
Q is empty
Q is empty
Q is empty
Q is empty
Q is empty
Q is empty
Qualcuno potrebbe spiegarmi perchè?
Volevo replicare l'OOP in C...
L'originale era
#include <iostream.h>
#define TAB '\t'
class Q {
                  private:
                  int back;
                  char data[10];
                 public:
                 void JoinQ(char ch);
                 void LeaveQ(void);
                 void ShowQ(void);
                 Q(void);
};
Q::Q()
{ 
    back = 0;
}
void Q::ShowQ(void)
{
     int x;
     if (back == 0)
    {
        cout << "Q is empty" << endl << endl;
     }
     else
    {
         for (x = 1; x <= back; x++)
        {
            cout << data[x] << TAB;
         }
         cout << endl << endl;
     }
}
void Q::JoinQ(char ch)
{
       if (back < 9)
      {
          back++;
          data[back] = ch;
       }
       else
       cout << "Q is full" << endl;
}
void Q::LeaveQ(void)
{
     int index;
     for (index = 1; index < back; index++)
    {
       data[index] = data[index + 1];
    }
    back--;
}
main()
{
     Q One;
     One.ShowQ();
     One.JoinQ('Z');
     One.ShowQ();
     One.JoinQ('A');
     One.ShowQ();
     One.JoinQ('K');
     One.ShowQ();
     One.LeaveQ();
     One.ShowQ();
     One.LeaveQ();
     One.ShowQ();
     One.LeaveQ();
      One.ShowQ();
     return(0);
}

Volevo replicare l'OOP in C...
Il problema e' che ogni "metodo" si alloca un nuovo
oggetto (chiamata new_Q) e quindi questo e' vuoto.
Questo evidenzia anche un altro problema... nelle
dichiarazioni di metodo non hai passato il "this":
ogni metodo deve sapere su quale oggetto agire.
Qualcosa di simile a quello che vuoi fare potrebbe
essere questo...
  typedef struct TAGQ
  {
    int back;
    char *data[10];
    void (*JoinQ)(struct tagQ *me,char *ch);
    void (*LeaveQ)(struct tagQ *me);
    void (*ShowQ)(struct tagQ *me);
    void (*ClearQ)(struct tagQ *me);
  } Q;
  void ClearQ(struct tagQ *me)
  {
    me->back=0;
  }
  void ShowQ(struct tagQ *me)
  {
    if (me->back==0)
    {
      printf("Q is empty\n");
    }
    else
    {
      int x;
      for (x=1; x<=me->back; x++)
        printf("%s\t",me->data[x]);
      printf("\n");
    }
  }
  ... e cosi' via ...
  int main()
  {
    One->ShowQ(One);      /* E' necessario passare il "this" */
    One->JoinQ(One,"Z");
    One->ShowQ(One);
    One->JoinQ(One,"A");
    ...
    return 0;
  }
NOTA:
   scritto al volo e non compilato... ma dovrebbe
   rendere l'idea
Spero tu abbia validi motivi per scrivere cose del genere
in C... non sarebbe piu' comodo usare un compilatore C++
che in pratica scrive queste cose in automatico (solo un
po' piu' efficienti), senza commettere errori e cercando
quando possibile di evitare a te di commetterne ?
Tempo fa io ho scritto molto codice OO in C usando sistemi
simili ma a oggi non riterrei piu' questa scelta sensata
tranne che per motivi molto molto specifici.
Andrea