Gå til innhold

Referanser til medlemmer av class/struct


Anbefalte innlegg

Jeg har en struktur med mange medlemmer. Mange av disse medlemmene er forskjellige variabler (ikke arrays) som jeg ønsker å tildele verdier. Siden jeg fyller opp mange variabler om gangen, så synes jeg at det er litt overflødig å måtte referere til strukturen *hver* gang jeg ønsker å bruke en medlemsvariabel eller medlemsfunksjon. Se f.eks på:

struct ting{
 int ting_nummer;
 char navn[50]; // inkl. "padding"
 char beskrivelse[200];
 struct tang{
   int tang_nummer;
   char navn_tang[50];
   char beskrivelse[200];
 }andre_egenskaper;
 }egenskaper;

Hver gang jeg skal bruke et medlem i strukturen tang er jeg nødt til å innlede med egenskaper.

 

Finnes det ikke en måte som forteller kompilatoren at samtlige variabler innenfor disse klammeparantesene finnes i struktur egenskaper?

Endret av Manuel
Lenke til kommentar
Videoannonse
Annonse
Hver gang jeg skal bruke et medlem i strukturen tang er jeg nødt til å innlede med egenskaper.

 

tang_nummer er et medlem av tang, og jeg trenger ikke bruke scope-operatoren her:

 

 ting::tang i_tang;
 i_tang.tang_nummer = 321;

 

jeg refererer kun til den ytre strukturen når jeg skal ha tak i den indre strukturen for å lage en instans .. etterpå refererer jeg ikke til strukturen, men til instansen - og dens medlemmer, direkte uten bruk av scope-operator..

 

..så du må forklare bedre - bruk et kjørbart eksempel, med kommentarer som viser hva du vil (hvilke detaljer du lurer på om er mulig å abstrahere vekk, om de ikke allerede er de som kommer frem i ex. mitt over da ... :) )

 

 

 

om du mener noe slikt, så vet jeg ikke om det er mulig i C++, kanskje med noe template-trickery (dette er Common Lisp):

(defclass Test ()
 ((navn :accessor navn :initarg :navn)
  (alder :accessor alder :initarg :alder)))

(let ((person-1 (make-instance 'Test :navn "Lars" :alder 25))
      (person-2 (make-instance 'Test :navn "Elisabeth" :alder 20)))
 (with-accessors ((navn-1 navn) (alder-1 alder)) person-1
   (with-accessors ((navn-2 navn) (alder-2 alder)) person-2
     (print navn-1) (print alder-1)
     (print navn-2) (print alder-2))))

"Lars"

25

"Elisabeth"

20

 

 

Edit:

det er mulig ting er annerledes mellom C og C++ her også ... jeg antok at du bruker C++ jeg da men ....

Endret av dayslepr
Lenke til kommentar

Virker som du vil operere på medlemmet andre_egenskaper av objektet egenskaper? Da er det ikke verre enn å opprette en referanse direkte til andre_egenskaper. F.eks:

ting::tang &andre = egenskaper.andre_egenskaper;
strncpy(andre.navn_tang, "hihi", 50);

Mulig at jeg misforstår hva du vil fram til, men med tanke på at du faktisk har definert objektene egenskaper og andre_egenskaper går jeg ut i fra at det er dette du vil.

 

Edit: Forresten har språket D et nøkkelord with som gjør at du kan operere med et visst skop i en blokk. Mistenker at det er noe slikt du spør etter, men jeg vet ikke hva helt hva jeg skal synes om det.

Endret av A_N_K
Lenke til kommentar

#include <cstdio>
#include <iostream>
#include "require.h"
using namespace std;

struct Stack{
struct Link{
 void* data;
 Link* next;
 void initialize(void* dat, Link* nxt) {
     data = dat;
     next = nxt;
 }
}* head;

void initialize() { head = 0; }

void push(void* dat) {
   Link* newLink = new Link;
   newLink->initialize(dat, head);
   head = newLink;
}

void* peek() { 
   require(head != 0, "Stack empty");
   return head->data; 
}

void* pop() {
   if(head == 0) return 0;
   void* result = head->data;
 	Link* oldHead = head;
   head = head->next;
   delete oldHead;
   return result;
}

void cleanup() {
   require(head == 0, "Stack not empty");
} 
};

void setstring(char szTarget[], char szIn[]){
int i = 0;
do {
 szTarget[i] = szIn[i];
} while(szIn[i++] != '\0');
}

struct Video_Management{
int serial; //unikt tall for hver film
char rental_date[6]; //Utleie- og innleveringsdato i formatet DD/MM
char return_date[6]; //Siste tegn fungerer som terminering, så hvis denne settes til noe
     // annet enn '/0' blir det et problem!
int nCount; // antall ganger utleid
char name[50]; // filmens navn
int released; // utgivelsesdato, år
char notes[200]; // andre notater

void PrintInfo(void){
 printf("Tittel: %s\n", name);
 printf("Serienummer: %d\n", serial);
 printf(" Utgivelsesaar: %d\n", released);
 printf(" Sist utleid: %s\n", rental_date);
 printf(" Sist tilbakelevert: %s\n", return_date);
 printf(" Antall ganger utleid: %d\n", nCount);
 printf("NOTATER: %s\n", notes);
}
int Rent(char* sz, char (*operation)){
 int i = 4;
 while(i > 0){
 	if((sz[i] < 47) || (sz[i] > 57))
   return -1;
 	i = i - 1;
 }
 setstring(operation,sz);
 nCount = nCount + 1;
 return 0;
}
};


int main(){
Stack videos;
Video_Management v1, v2, v3;
v1.Rent("31/05", v1.rental_date),v1.Rent("01/06", v1.return_date);
v1.serial = 5594;
v1.nCount = 1;
setstring(v1.name, "The Rock");
v1.released = 1998;
setstring(v1.notes, "Finnes både på VHS og DVD som tosidig plate");

v2.Rent("06/07", v2.rental_date), v2.Rent("07/07", v2.return_date);
v2.serial = 5492;
v2.nCount = 4;
setstring(v2.name, "Crimson Tide");
v2.released = 1995;
setstring(v2.notes, "Denne har jeg bare på VHS");

v3.Rent("08/08", v3.rental_date),v3.Rent("09/08", v3.return_date);
v3.serial = 5444;
v3.nCount = 6;
setstring(v3.name, "Mission: Impossible");
v3.released = 1997;
setstring(v3.notes, "Denne finnes både på VHS og DVD");

videos.initialize();
videos.push(static_cast<void*>(&v1));
videos.push(static_cast<void*>(&v2));
videos.push(static_cast<void*>(&v3));
Video_Management* vp;
vp = static_cast<Video_Management*>(videos.pop());
((*vp).PrintInfo());
(*((Video_Management*)(videos.pop()))).PrintInfo(); //En skikkelig stygg peker-i-peker-i-masse-paranteser-variant
(*((Video_Management*)(videos.pop()))).PrintInfo();
videos.cleanup();
return 0;
}

require.h inneholder bare noen enkle funksjoner som tar i bruk cassert.

 

Stack-strukturen fungerer som stack-segmenter i assembly, med push, pop osv. Dette er skrevet som en del av en oppgave. Min oppgave var å lage en struktur som representerer en videofilm til en utleiebutikk, med alle egenskaper jeg finner passende. Jeg lager altså tre objekter av typen "Video_Management", og tildeler disse egenskaper som serienummer, utleiedata, innleveringsdato osv. Stack-objektet, "videos", er i grunn overflødig, men dette er altså oppgaven. Programmet avsluttes ved å "poppe" stacket, og kaste void-pekere tilbake til Video_Management-pekere.

 

Spørsmålet dreier seg om denne delen:

 

v1.Rent("31/05", v1.rental_date),v1.Rent("01/06", v1.return_date);
v1.serial = 5594;
v1.nCount = 1;
setstring(v1.name, "The Rock");
v1.released = 1998;
setstring(v1.notes, "Finnes både på VHS og DVD som tosidig plate");

v2.Rent("06/07", v2.rental_date), v2.Rent("07/07", v2.return_date);
v2.serial = 5492;
v2.nCount = 4;
setstring(v2.name, "Crimson Tide");
v2.released = 1995;
setstring(v2.notes, "Denne har jeg bare på VHS");

v3.Rent("08/08", v3.rental_date),v3.Rent("09/08", v3.return_date);
v3.serial = 5444;
v3.nCount = 6;
setstring(v3.name, "Mission: Impossible");
v3.released = 1997;
setstring(v3.notes, "Denne finnes både på VHS og DVD");

Her referer jeg til v1, v2 og v3 flere ganger på rad. Det hadde vært fint om det var mulig å begrense det til èn gang ved å si at "mellom disse klammeparantesene så refererer jeg bare til instanser ( ? ) i objektet v1".

 

edit: Virker som om forumet ikke liker tabulator...

Endret av Manuel
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...