Gå til innhold

Enkel peker vs dobbel peker


Anbefalte innlegg

Slik er klassene fordelt:

 

Arv:

Basisklasse->subklasse

 

Person-->Owner

 

 

Vehicle->Motor_vehicle-->Private_car

Vehicle->Motor_vehicle-->Bus

Vehicle->Motor_vehicle-->Truck

 

I klassen Owner skal medlemsdata være blant annet antall Motor_vehicles og en tabell av Motor_vehicles

 

I utgangspunktet hadde jeg medlemsdata lagt opp slik for Owner:

Owner.h

int antallKjoretoy;

Motor_vehicle* carCollection;

 

Vi har fått tips til oppgaven at tabellen for Motor_vehicle skal ikke være med en peker men to. Dvs. Motor_vehicle** carCollection.

 

Kan noen forklare hvorfor det bør være av to pekere og ikke en? Hva er egentlig forskjellen mellom en peker vs to pekere? Hva oppnår vi ved to pekere som man ikke gjør ved en?

 

På forhånd takk ;)

Endret av mesha
Lenke til kommentar
Videoannonse
Annonse

Slik er klassene fordelt:

 

Vehicle->Motor_vehicle-->Private_car

Vehicle->Motor_vehicle-->Bus

Vehicle->Motor_vehicle-->Truck

 

I klassen Owner skal medlemsdata være blant annet antall Motor_vehicles og en tabell av Motor_vehicles

 

Mm... dvs. en Owner::carCollection skal kunne peke til (1. elementet i) en array av flere Motor_vehicles.

 

I utgangspunktet hadde jeg medlemsdata lagt opp slik for Owner:

Owner.h

int antallKjoretoy;

Motor_vehicle* carCollection;

 

Da kan en Owner ha kun 1 element i carCollection.

 

Vi har fått tips til oppgaven at tabellen for Motor_vehicle skal ikke være med en peker men to. Dvs. Motor_vehicle** carCollection.

 

Jeg ville ha brukt std::vector<boost::shared_ptr<Motor_vehicle> > v, men ok.

 

Kan noen forklare hvorfor det bør være av to pekere og ikke en?

 

"Av to pekere"?

 

Hva er egentlig forskjellen mellom en peker vs to pekere?

 

To pekere?

 

Det er litt terminologiforvrirring, muligens:

 

T *p;   // pointer to T
T **pp; // pointer to a pointer to T

 

Forskjellen mellom disse er hva som kan lagres i dem. p inneholder adressen til et objekt av typen T. p inneholder adressen til et objekt av typen "pointer-to-T".

 

Når det gjelder situasjonen med arv, spesifikt, så kan du la en peker til baseklassen B peke på et objekt av typen subklassen-til-B. Men selv om du skulle ha flere subklasser-til-B liggende etter hverandre i minne (bedre kjent som array), kan du IKKE bruke en peker-til-B til å aksessere elementene i det arrayet. Derav (antageligvis?) rådet om å bruke peker-til-peker-til-baseklasse.

Lenke til kommentar

Beklager ang terminologien, men du har forstått meg riktig hvertfall:) Takker og bukker for svar:)

 

Vil bare legge til at konstruktøren min ser slik ut for Owner:

Owner::Owner()

{

//Utganspunkt i at medlemsdata for Owner er slik "Motor_vehicle** carCollection;"

carCollection = new Motor_vehicle[10];

//er litt usikker ang syntaxen, er det slik heller "carCollection = new Motor_vehicle*[10];"?

}

 

Har jeg oppfattet det riktig?

 

Motor_vehicle** carCollection;

//En peker som peker til en tabell med pekere, hvor pekerne peker på T objekter, eller i mitt tilfelle Motor_vehicle objekter

 

Motor_vehicle* carCollection;

//En peker som peker til eksakt et objekt av Motor_vehicle

//Men er dette lov " carCollection = new Motor_vehicle[10];"? Ihvertfall hva er forskjellen fra imotsetning til " carCollection = new Motor_vehicle*[10];"?

 

Beklager hvis det blir mye fram og tilbake. Håper det er leselig

 

På forhånd takk;)

Lenke til kommentar

Vil bare legge til at konstruktøren min ser slik ut for Owner:

 

Owner::Owner()

{

//Utganspunkt i at medlemsdata for Owner er slik "Motor_vehicle** carCollection;"

carCollection = new Motor_vehicle[10];

//er litt usikker ang syntaxen, er det slik heller "carCollection = new Motor_vehicle*[10];"?

}

 

carCollection er en peker til en haug av Motor_vehicle-pekere. Altså:

 

carCollection = new Motor_vehicle*[10];

 

Motor_vehicle** carCollection;

// En peker som peker til en tabell med pekere, hvor pekerne peker på T objekter,

// eller i mitt tilfelle Motor_vehicle objekter

 

En pointer-to-pointer-to-T trenger ikke å peke på det 1. elementet av et array av pointer-to-T, men det er en av mulighetene. Forresten, det er en forskjell mellom "peker til et array av T" og "peker til peker til T". Det som gjør det enda mer forvirrende er at array-av-T konverteres implisitt til peker-til-T når arrayet blir sendt som et argument:

 

Så:

 

struct Base {
   virtual void f(){}
};

struct Derived : Base
{ 
   virtual void f(){}
};

void foo(Base *b)
{
   b->f();            // success, call arr1[0].f();
   b[1].f();          // error (typically, segmentation fault/illegal instruction)
}

int main()
{
   Derived arr1[10];  // array of 10 Derived objects
   foo(arr1);

   Base* arr2[10];    // array of 10 pointer-to-Base
   for ( size_t i = 0; i != 10; ++i )
       arr2[i] = &arr1[i];

   Base **bpp;        // bpp is pointer-to-pointer-to-Base
   bpp = &arr2[0];    // bpp has the address of the first element of arr2
   (*bpp)->f();       // ok, call arr1[0].f() 
   bpp[1]->f();       // ok, call arr1[1].f()

   Derived (*ap)[10] = &arr1; // ap is a pointer to array 10 of Derived.
   (*ap)[3].f();      // ok, call arr1[3].f()
}

 

Da burde vel både pointer-to-T, pointer-to-pointer-to-T og pointer-to-array-of-T være dekket. Peter van der Linden har en veldig bra forklaring på forskjeller og likheter mellom arrays og pekere i C (tilsvarende gjelder for C++) i boken "Expert C programming" (aka "the ugly fish book").

 

Motor_vehicle* carCollection;

//En peker som peker til eksakt et objekt av Motor_vehicle

 

... eller Motor_vehicle sin subklasse.

 

//Men er dette lov " carCollection = new Motor_vehicle[10];"?

 

Ja, men da får du ikke brukt subklassene til Motor_vehicle.

 

Ihvertfall hva er forskjellen fra imotsetning til " carCollection = new Motor_vehicle*[10];"?

 

Forskjellen er hva det arrayet som du allokerer inneholder. Tegn det på papiret.

 

Bonus for det hele er spørsmålet om eierskap av objektene når du har et array av pointer-to-T. Derav min opprinnelige anbefaling om vector<shared_ptr<T>>.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...