Avatar billede krismort Nybegynder
21. august 2002 - 00:03 Der er 7 kommentarer og
2 løsninger

klasse konvertering

Jeg har en masse klasser som har det tilsammen at de skal konverteres til et 'seriel' byte array.
Et eksempel på en klasse kunne se sådan ud:
class C1
{
    int v1;
    float v2;
    DWORD  v3;
    byte v4[15];
}; 
en anden klasse kunne se sådan ud
class C2
{
    int v1;
    byte v2[7];
    byte v3[255];
};

det eneste som er fælles for de klasser er den første variabel v1 som angiver hvilken type classe der er tale om. Indtil viderer har jeg skrevet en funktion for hver enkelt klasse hvor jeg 'manuelt' serialiserer dem.
KAn det ikke gøres på en meget nemmerer måde ? Jeg tænkte feks på om det var muligt at caste de klasser ind i et byte array eller noget med reinterpret_cast!
Jeg kan bare ikke få det til at fungerer helt... det vil sige jeg kan få det til at fungerer lidt.. hvis jeg gør således caster den nemlig den første variabel. men ikke de andre

class C2
{
    int v1;
    byte v2[7];
    byte v3[255];
   
    C1() {
        v1 = 2;
    };
    byte* serialize() {
        return reinterpret_cast <byte*> (this);
    };
};

Håber der er en der kan hjælp mig med dette lille problem

Kristian
Avatar billede chries Nybegynder
21. august 2002 - 08:48 #1
hvad med :

C1 c;

byte *pByte = reinterpret_cast <byte*> (&c);
int nBytes = sizeof( C1 );
Avatar billede chries Nybegynder
21. august 2002 - 08:52 #2
jeg kunne forestille mig du tager sizeof af en pointer "f.eks sizeof(pByte)" og derfor kun får de fire første bytes i dit eget kode.
Avatar billede soepro Nybegynder
21. august 2002 - 11:26 #3
Du skal lave en basis-klasse, som indeholder det som er fælles for de to, og så lave nedarving fra dem. I din basis-klasse laver du så en virtuel function -serialize- som du definerer i dine nedarvede klasser. På den måde kan du bruge serialize metoden i din standard funktion, som så bare tager basis-klassen som parameter:
Avatar billede soepro Nybegynder
21. august 2002 - 11:33 #4
class CX
{
  protected: // kun denne eller nedarvede klasser
    int v1;
  public:
    virtual byte* serialize(void);
};

class C1 : CX
{
  protected: // kun denne eller nedarvede klasser
    // int v1; findes i CX
    float v2;
    DWORD  v3;
    byte v4[15];
  public:
    virtuel byte* serialize(void);
};
byte * C1::serialize(void)
{
  return v4;
}
 
en anden klasse kunne se sådan ud
class C2 : CX
{
  protected: // Kun denne eller nedarvede klasser.
    // int v1; findes i CX
    byte v2[7];
    byte v3[255];
  public:
    virtuel byte* serialize(void);

};
byte * C2::serialize(void)
{
  return v3;
}

void globalSerialize(CX vCX)
{
  cprintf("%.255s", vCX.serialize());
}

int main(void)
{
  C1 vC1;
  C2 vC2:

  globalSerialize(C1);
  globalSerialize(C2)
  return 0;
}

Første globalSerialize kald vil ende med at kalde C1's serialize function, anden globalSerialize kald vil ende med at kalde C2's serialize function.
Avatar billede chries Nybegynder
21. august 2002 - 11:42 #5
soepro du mangler de meste af indholdet i klasserne når du "serialsierer dem". f.eks i C1 får du kun v4 med og ikke v3,v2,v1
Avatar billede soepro Nybegynder
21. august 2002 - 11:54 #6
chries >> Jeg har ikke lagt nogen betydning i serialize funktionen, kun vist princippet. krismort kan jo ændre dem helt som han ønsker det, f.eks.

byte * C1::serialize(void)
{
  AnsiString tmpStr = "C1 indeholder:\r\nV1 = " + IntToStr(v1) + "\r\n"
                    + "V2 = \'" + v2 + "\'\r\n"
                    + "V3 = \'" + v3 + "\'\r\n";
  return (byte *)tmpStr.c_str();
}

Eller hvad der nu passer til formålet.
Avatar billede chries Nybegynder
21. august 2002 - 12:51 #7
Ja, ok. Men synes nu du er lidt hurtig på aftrækkeren :-)
i udvidelsen returner du en pointer til en lokal variabel.
Avatar billede soepro Nybegynder
21. august 2002 - 12:58 #8
chries >> tilføj static foran AnsiString, så er det løst. (Det er stadig kun princippet - ikke færdige løsninger !)
Avatar billede chries Nybegynder
21. august 2002 - 13:14 #9
Jeg giver dig da gerne ret i det kun er principper, men det er stadig ingen grund til at servere potentionelle faldgruber.

static løser problemet, men kun begrænset. Klad til forskelle instanser, ødelægger det retunerede.

class C1
{
    public:
        int* Test();
};

int* C1::Test()
{
    static int i = 0;
    i++;
    return &i;
}

void main(void)
{
    C1 T1;
    int *p1 = T1.Test();

    cout << "P1: " << *p1 << endl;

    C1 T2;
    int *p2 = T2.Test();

    cout << "P1: " << *p1 << ", P2: " << *p2 << endl;
}

output:
P1: 1
P1: 2, P2: 2
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester