2013-02-09 3 views
3

Est-il possible d'avoir une structure contenant des références à des structures. Et comment sont-ils initialisés? Voir le court exemple ci-dessous.initialize struct contient des références aux structures

Merci

typedef struct { 
    int a; 
}typeInner1; 


typedef struct { 
    int b; 
}typeInner2; 


typedef struct { 
    typeInner1 &one; 
    typeInner2 &two; 
}typeOuter; 

void fun2(typeOuter *p){ 
    p->one.a =2; 
    p->two.b =3; 
} 


void fun(typeInner1 &arg1,typeInner2 &arg2){ 
    typeOuter *ptr = new typeOuter;//<-- how to write initializer 
    fun2(ptr); 
} 


int main(){ 
    typeInner1 arg1; 
    typeInner2 arg2; 
    fun(arg1,arg2); 

    //now arg1.a should be 2 and arg2.a=3 
} 

de Ok merci pour toutes les entrées. J'ai aussi dû modifier le typedef du typeOuter pour le faire fonctionner. Plein code de travail ci-dessous pour d'autres personnes trouvant ce poste.

#include <cstdio> 
typedef struct { 
    int a; 
}typeInner1; 


typedef struct { 
    int b; 
}typeInner2; 


typedef struct typeOuter_t { 
    typeInner1 &one; 
    typeInner2 &two; 
    typeOuter_t(typeInner1 &a1, typeInner2 &a2) : one(a1), two(a2) {} 
}typeOuter; 

void fun2(typeOuter *p){ 
    p->one.a =2; 
    p->two.b =3; 
} 


void fun(typeInner1 &arg1,typeInner2 &arg2){ 
    typeOuter *ptr = new typeOuter(arg1,arg2); 
    fun2(ptr); 
} 


int main(){ 
    typeInner1 arg1; 
    typeInner2 arg2; 
    fun(arg1,arg2); 

    //now arg1.a shoule be 1 and arg2.a=3 
    fprintf(stderr,"arg1=%d arg2=%d\n",arg1.a,arg2.b); 
} 
+0

BTW, struct 'typedef {...} foo,' est pas "idiomatiques" en C++, écrire simplement 'struct foo {...};' est plus courant (et permet d'utiliser directement 'foo' comme nom de type). – Mat

Répondre

3

Donnez typeOuter un constructeur approprié:

struct typeOuter 
{ 
    typeInner1 &one; 
    typeInner2 &two; 
    typeOuter(typeInner1 &a1, typeInner2 &a2) : one(a1), two(a2) {} 
}; 



void fun(typeInner1 &arg1, typeInner2 &arg2) { 
    typeOuter *ptr = new typeOuter(arg1, arg2); 
    fun2(ptr); 
} 
2

En C++, vous pouvez créer un constructeur pour votre struct. Les structures sont essentiellement des classes avec public comme modificateur d'accès par défaut.

struct Example 
{ 
    // struct fields.. 

    Example(); // initialize struct objects. 
    ~Example(); // perform clean up if necessary. 
}; 
1

Votre problème n'est pas d'avoir des références à struct s, mais avec des références en général initialisation. Les références ne peuvent pas être initialisées par défaut, qu'elles soient des références à un struct ou à un type prédéfini.

int& x; // ERROR! Non-initialized reference to int 
C& y; // ERROR! Non-initialized reference to a struct C 
int z; 
C w; 
int& a = z; // OK: Initialized reference to int 
C& b = w; // OK: Initialized reference to struct C 

Lorsque vos références sont des variables membres d'un struct, d'autre part (peu importe quel type ils se réfèrent à), ils doivent être liés dès que votre struct est construit (comme références régulières). Construire par défaut votre struct, puis lier les références n'est pas une option, car cela se fait en deux étapes, et les références ne seraient pas initialisées après la première étape.

Par conséquent, vous devez fournir un constructeur pour votre struct et initialiser vos références là:

struct typeOuter { 
    typeOuter(typeInner1& o, typeInner2& t) : one(o), two(t) { } 
    typeInner1 &one; 
    typeInner2 &two; 
};  

Votre fonction fun() alors ressembler à ceci:

void fun(typeInner1 &arg1,typeInner2 &arg2){ 
    typeOuter *ptr = new typeOuter(arg1, arg2); 
    fun2(ptr); 
} 
2

Avant C++ 11, vous aurez besoin d'un constructeur pour votre structure typeOuter, et initialisez les références de membre dans la liste d'initialisation:

typeOuter(typeInner1& i1, typeInner2& i2) : one(i1), two(i2) {} 

Avec 11 C++, vous avez également la possibilité d'utiliser une liste d'initialisation directement (sans définir un constructeur vous):

typeOuter *ptr = new typeOuter { arg1, arg2 }; 
1

Vous pouvez ajouter un constructeur, mais vous pouvez également utiliser l'initialisation globale avec une fonction d'usine. Cela fonctionne dans toutes les versions de C++:

struct A 
{ 
    int& i; 
}; 

A make_a(int& i) 
{ 
    A a = {i}; 
    return a; 
} 

int main() 
{ 
    int i = 0; 
    A* a = new A(make_a(i)); 
} 
0

Uhm ..

#include <cstdio> 

struct typeInner1 
{ 
    typeInner1(int a = 0) : m_a(a) {} // typeInner1 constructor 
    int m_a; 
}; 

struct typeInner2 
{ 
    typeInner2(int b = 0) : m_b(b) {} // typeInner2 constructor 
    int m_b; 
}; 

struct typeOuter 
{ 
    typeOuter(typeInner1& one, typeInner2& two) : m_one(one), m_two(two) {} // typeOuter constructor 

    typeOuter& set(int a, int b) { m_one.m_a = a; m_two.m_b = b; return *this; } 
    typeOuter& print() { printf("typeInner1 a is %i and typeInner2 b is %i\n", m_one.m_a, m_two.m_b); return *this; } 

    typeInner1& m_one; 
    typeInner2& m_two; 
}; 

typeOuter fun(typeInner1& arg1, typeInner2& arg2) 
{ 
    return typeOuter(arg1, arg2); 
} 

int main() 
{ 
    typeInner1 arg1; 
    typeInner2 arg2; 

    fun(arg1, arg2).print().set(101, 202).print().set(202, 303).print(); 

    return 0; 
} 

Sorties

typeInner1 a is 0 and typeInner2 b is 0 
typeInner1 a is 101 and typeInner2 b is 202 
typeInner1 a is 202 and typeInner2 b is 303 
Questions connexes