2010-12-16 9 views
3

Gibt es eine Möglichkeit, diese Situation in C++ zu simulieren?Zeiger auf das Attribut eines Zeigers

Ich habe zwei Objekte A und B, jedes hat ein Attribut, zum Beispiel int i; Auch ich habe einen Zeiger po zeigt auf ein Objekt und einen Zeiger pi zeigt auf eine ganze Zahl. Ich möchte, dass der Integer-Zeiger auf das Attribut im aktuellen Objekt zeigt, auf das der Zeiger zeigt. Etwas wie:

po = A; 
pi = po->i; 
// pi points to A.i 
po = B; 
// now pi points to B.i 

Ich bin fast sicher, dass dies nicht mit Zeigern erreicht werden kann, aber ich möchte wissen, ob es um eine Arbeit zu tun.

+0

Dies könnte mit einer Struktur erfolgen, die sich wie Zeiger auf int verhält, aber einen Verweis auf einen anderen Zeiger enthält, sowie einen Zeiger auf ein Element. Aber wirklich, warum Dinge komplizieren? Was immer Sie hier erreichen wollen, ist sicherlich eleganter. – Dialecticus

+0

Ich vermute, nach Ihrer Beschreibung ist B von A abgeleitet (Sie weisen Zeiger zu.) Wenn ja, ist A :: i das gleiche wie B :: i. Sie müssen klären, was Sie tatsächlich tun, bevor jemand Ihnen helfen könnte. –

+0

In aller Ernsthaftigkeit würde ich diese Magie jedoch nicht in realem Code einsetzen - warum stellen Sie nicht einfach eine Zugriffsmethode für "i" zur Verfügung? – Nim

Antwort

-4
struct S { 
    int i; 
}; 


S a, b; 
A * ap = & a; 
int * ip = &(ap->i); 

ip verweist nun auf ein i Mitglied ist (beachten Sie diese nicht bezeichnet als Attribute in C++ Land)

+0

Bitte lesen Sie die Frage noch einmal sorgfältig durch. –

+0

Das ist nicht das, wonach das OP gefragt hat. Er möchte, dass der Wert von 'pi' automatisch geändert wird, wenn' po' geändert wird. –

+0

Er sagte: "Ich möchte, dass der Integer-Zeiger auf das Attribut im aktuellen Objekt zeigt, auf das der Zeiger zeigt", was der von mir gepostete Code ist. –

0

Wie Sie es geschrieben haben:

pi weiter Ai zeigen, wenn po Punkte zu B.

Was bei der Verwendung von

po = &A; 
// do stuff using po and po->i (A and A.i) 

po = &B; 
// do stuff using po and po->i (B and B.i) 
+0

Nun, eine gültige Frage, aber es versucht nicht, OP's * eigentliche Frage * –

0

kurz falsch ist, dies kann nicht getan die wie du es spezifiziert hast. Noch würden Sie wirklich wollen es.

Stellen Sie sich einfach das Chaos vor, das auf Ihre Anwendung herabregnen würde, wenn das Ändern einer Variablen auch andere völlig unterschiedliche Variablen ändert. Es wäre wie Hunde & Katzen zusammen zu leben. Massenhysterie.

Aber es ist auch wenig sinnvoll, genau das zu tun, was Sie gefragt haben, und das lässt mich denken, dass das, was Sie sind wirklich ist, ist etwas ganz anderes. Zum Beispiel in Ihrem obigen Beispiel würde es dies viel einfacher zu einfach tun:

po = A; 
int ai = po->i; 
po = B; 
int ab = po->i; 

Also, was sind Sie wirklich versuchen zu tun?

+0

zu beantworten, was ich sagte :-) – DanS

+0

Nicht genau. Du hast gesagt (paraphrasierend) "warum nicht?" Ich sagte: "Das kannst du nicht tun. Was willst du wirklich tun? In deinem erfundenen Beispiel, warum tust du das nicht?" –

4

Was Sie suchen, heißt "Zeiger auf Mitglieder". Nehmen wir an, dass A und B vom Typ T sind, dann können Sie schreiben:

struct T { int i; }; 
T A, B, C; // some objects of this type 

int T::*pi = &T::i; // pi is a pointer to an int member of T 

T* po; 
po = &A; 
cout << po->*pi << '\n'; // prints A.i 
po = &B; 
cout << po->*pi << '\n'; // prints B.i 

cout << C.*pi << '\n'; // prints C.i 
+0

Ja, das ist wahrscheinlich das, was OP wirklich will. Aber es wurde nicht gefragt, weshalb ich um weitere Erläuterungen bat. +1 –

2

Eigentlich Sie nicht, dass gerade nach vorne tun. pi müsste benachrichtigt/geändert werden, wenn po ändert. Mit pi als Objekt eines neuen Typs AutoReference können Sie es erreichen, aber niemand wird den Code verstehen. Was ich mit "nicht geradlinig" meine ist: Das Folgende funktioniert aber nicht.

class AutoReference 
{ 
public: 
    AutoReference(ClassA ** ppObj) 
    : mppObj(ppObj) 
    { 
    } 

    ClassA * operator->() 
    { 
    return *mppObj; 
    } 

private: 
    ClassA ** mppObj; 
}; 


po = A; 
AutoReference pi(&po); 
// pi "points" to A.i 
po = B; 
// now pi "points" to B.i 
+0

Eigentlich mag ich nicht den Namen 'AutoReference' :-( –

+0

+1 sollten Sie auch Operator & implementieren und * & um einen vollen Smart Pointer zu bieten. Aber ich mag Ihre Idee besser als meine, es ist einfacher , weniger schwer als meine –

2
struct O 
{ 
    int i; 
}; 

struct P 
{ 
    void operator=(O & rhs) 
    { 
     po = &rhs; 
     pi = &rhs.i; 
    } 

    O * po; 
    int * pi; 
}; 

int main() 
{ 
    P po; 
    int *& pi = po.pi; 

    O A,B; 
    A.i = 7; 
    B.i = 19; 

    po = A; 
    cout << *pi << endl; 
    po = B; 
    cout << *pi << endl; 
} 
0

Dies würde funktionieren, aber ich finde diese hässlich.

class MyObject 
{ 
public: 
int m_i; 

}; 

class AutomaticPointerToMember 
{ 
    public: 
AutomaticPointerToMember(MyObject& obj,int MyObject::*): 
m_Object(obj), 
m_pInt(NULL) 
{} 

    operator int*() 
{ 
    return &(m_Object.*m_pInt); 
} 

int operator*() 
{ 
    return (m_Object.*m_pInt); 
} 

private: 
MyObject& m_Object; 
int MyObject::* m_pInt; 
}; 

void test() 
{ 
MyObject a; 
MyObject b; 

MyObject * pObj = &a; 
AutomaticPointerToMember pi(*pObj, &MyObject::m_i); 

int * pIa = pi; // pIa points to a.i 
    int ia = *pi; // value a.i 

pObj = &b; // pObj now points to b 

int * pIb = pi; // pIb points to b.i 

    int ib = *pi; // value b.i 
} 

und man würde auch Betreiber definieren &, * & und so weiter, um einen politisch korrekten Smart-Pointer zu definieren ...

1

Oder Sie könnten einfach einen Zeiger auf den Zeiger tun, wenn das besser zu Ihrer Situation passt.

+0

+1 offensichtlich, einfach und elegant –

Verwandte Themen