2009-03-18 10 views
3

Es ist Zeit für meine erste Frage jetzt. Wie durchqueren Sie Zuweisungsoperatoren zwischen zwei Klassen?Crossing Zuweisungsoperatoren?

class B; 

class A { 
public: 
A &operator = (const B &b); 
friend B &B::operator = (const A &a); //compiler error 
}; 

class B { 
public: 
B &operator = (const A &a); 
friend A &A::operator = (const B &b); 
}; 

Ich suchte nach, wie eine Memberfunktion wie weiterleiten erklären:

class B; 
B &B::operator = (const A &a); //error 

Aber ich irgendetwas nicht finden. Und ich möchte nicht, dass die Klassen alle miteinander befreundet sind. Wie mache ich das?

+0

Ich frage mich, wie willst du das verwenden? –

+0

Bumhunter. Hm ... –

+0

@Earwicker: wem war das? –

Antwort

1

Der Grund für den Compilerfehler ist eine zirkuläre Abhängigkeit. Jede Ihrer operator =() -Funktionen erfordert die Kenntnis der operator =() -Funktion innerhalb der anderen Klasse. Daher wird es immer einen Fehler geben, unabhängig davon, in welcher Reihenfolge Sie Ihre Klassen definieren.

Hier ist eine Möglichkeit, es zu lösen. Es ist nicht sehr elegant, aber es wird tun, was Sie wollen:

class A; 
class B; 

A & set_equal(A & a, const B & b); 
B & set_equal(B & a, const A & a); 

class A 
{ 
    private: 
     int x; 
    public: 
     A & operator=(const B & b) { return set_equal(*this, b); } 
     friend B & set_equal(B & b, const A & a); 
     friend A & set_equal(A & a, const B & b); 
}; 

class B 
{ 
    private: 
     int y; 
    public: 
     B & operator=(const A & a) { return set_equal(*this, a); } 
     friend A & set_equal(A & a, const B & b); 
     friend B & set_equal(B & b, const A & a); 
}; 

A & set_equal(A & a, const B & b) { a.x = b.y; return a; } 
B & set_equal(B & b, const A & a) { b.y = a.x; return b; } 

Sie können auch in der Lage sein, dieses Problem mit Vererbung zu lösen.

bearbeiten: Hier ist ein Beispiel mit Vererbung. Dies funktioniert, wenn das Kopierverfahren nur Zugriff auf einige gemeinsame Daten benötigt, die von A und B gemeinsam genutzt werden, was wahrscheinlich wäre, wenn der = Operator irgendeine Bedeutung haben soll.

class A; 
class B; 

class common 
{ 
    protected: 
     int x; 
     void copyFrom(const common & c) { x = c.x; } 
}; 

class A : public common 
{ 
    public: 
     A & operator=(const common & c) { copyFrom(c); return *this; } 
}; 

class B : public common 
{ 
    public: 
     B & operator=(const common & c) { copyFrom(c); return *this; } 
}; 
+1

@recent downvoter: Was war mein Fehler? –

2

Es gibt keine Möglichkeit, Mitgliederfunktionen weiterzuleiten. Ich bin mir nicht sicher, ob es einen eleganteren Weg gibt, um das zu bekommen, was Sie wollen (ich hatte nie Grund, so etwas zu tun), aber was funktionieren würde, wäre, die zweite Klasse zu einer Nichtmitgliedsfunktion zu machen Das ist ein Freund für beide Klassen und delegiert das Kopieren an sie. Beachten Sie, dass Operator = kann nicht selbst ein Nicht-Mitglied, aber so etwas wie dies funktionieren soll:

class B; 

class A { 
public: 
    A& operator = (const B &b); 
    friend B& do_operator_equals (B& b, const A& b); 
}; 

class B { 
public: 
    B &operator = (const A &a); 
    friend A& A::operator = (const B &b); 
    friend B& do_operator_equals (B& b, const A& a); 
}; 

Und dann in Ihrer Implementierungsdatei

A& A::operator= (const B& b) { 
    // the actual code to copy a B into an A 
    return *this; 
} 

B& B::operator= (const A& a) { 
    return do_operator_equals(*this, a); 
} 

B& do_operator_equals(B& b, const A& a) { 
    // the actual code to copy an A into a B 
    return b; 
} 

Edit: Erhielten die a und B nach hinten, Hoppla. Fest.

+0

Ich denke, das ist der Weg zu gehen, aber ich werde nur beide gleich Operatoren für Konsistenz ändern. – Jonas

-3

Sie nicht weiterleiten deklarieren die Member-Funktion, Sie forward deklarieren die Klasse.

class B; // DECLARE class B but don't define its contents 

class A { // ... uses B as above 
}; 

class B { // ... now you define the class. 
}; 

Siehe die C++ FAQ section 39.

+0

-1, weil das Lesen seines Codes zeigt, dass er dies bereits versucht hat. Das Problem ist, dass beide Klassen sich gegenseitig referenzieren, was eine zirkuläre Abhängigkeit verursacht. –

0

Warum möchten Sie, dass sie in erster Linie Freunde sind?
Dies scheint unmöglich zu sein, wie Sie es schreiben. Die Lösung wäre wahrscheinlich, sie nicht als Freunde zu haben.

+0

Wenn sie keine Freunde sind, kann ich sie nicht so einfach kopieren. Die Lösung wäre dann, dass ich sie überhaupt nicht kopieren kann. Ich könnte eine Mitgliedsfunktion oder eine Kopierfabrik oder etwas Dummes benutzen, aber dann müsste das auch ein Freund sein ... – Jonas

Verwandte Themen