2009-03-17 2 views
9

Fast alle C++ - Projekte haben Klassen mit Kopie c-tor/Kopie Operator/Serialize-Methode usw. Was normalerweise etwas mit allen Mitgliedern zu tun.neues Mitglied zum Kopieren hinzufügen c-tor/Kopie O-Tor/Serialisierungserinnerung

Aber manchmal vergessen Entwickler, neue Mitglieder zu diesen Funktionen hinzuzufügen.
Kennen Sie einfach, nicht alle Mitglieder Weg, die Entwickler daran erinnern, etwas zu tun oder schreiben noop (memeber_name_) in diesen Funktionen.

Ich habe versucht, etwas zu erfinden, aber habe Schuld.

PS: Komponententests könnten dieses Problem verhindern, aber ich möchte etwas Kompilierzeit.

Antwort

1
template<class T> 
class SafeMember { 
public: 
    T _; /* short name for convenience */ 
    SafeMember(T const& obj) : _(obj) { } 
}; 

wie folgt verwendet:

class Student { 
public: 
    Student(string surname, Color hairColor) 
     : surname(surname) 
     , hairColor(hairColor) { } 

    Student(Student const& other) 
     : surname(other.surname) 
     , hairColor(other.hairColor) { } 

    Student& operator=(Student const& other) { 
     surname = other.surname; 
     hairColor = other.hairColor; 
     return *this; 
    } 

    string getSurname() const { return surname._; } 

    // The foo._ syntax is better than implicit conversion because 
    // it lets us call member functions, like substr in this example: 
    bool isSlavic() const {return surname._.substr(surname._.size()-2)=="ev";} 

    void dyeHair(Color newColor) { hairColor = newColor; } 

private: 
    SafeMember<string> surname; 
    SafeMember<Color> hairColor; 
}; 

Nun, wenn Sie ein „SafeMember<int> age“ Mitglied hinzufügen und vergessen Sie Ihre Kopie-Konstruktor zu aktualisieren, nicht die Kompilierung wird hilfreich.

Und für einen "no-op" Hinweis würde der Entwickler einen Initialisierer wie ": age (0)" hinzufügen.

Hinweis: dies schützt nicht Ihre Operator =() oder serialize() -Funktionen von bit-rot, nur die Konstruktoren. Hoffentlich sollte dies jedoch genug sein: Wenn Sie Ihre Auslassungen in den Konstruktoren sehen, werden Sie wahrscheinlich daran denken, auch die anderen Funktionen zu durchlaufen.

+0

"nicht alle Mitglieder Weg". –

+0

Nun, SafeMember macht es einfach genug, sie zu wickeln. Ich denke, OP möchte vermeiden, sie manuell zu verpacken. –

+0

Sorry, aber es funktioniert mit neuen Member-Variable .. Ich habe Erinnerung nur für Standardkonstruktor. – bayda

0

Es sieht aus als gäbe es keine zufriedenstellende Lösung für Ihr Problem (Iraimbilanja Lösung ist wahrscheinlich einer der besten Ansätze, aber immer noch ist es nicht perfekt). Ich frage mich, ob es in kommenden C++ 0x Features gibt, die es erlauben, das zu lösen?

+0

Ich bin weiterhin versuchen, eine akzeptable Lösung zu finden :) Es wird akzeptabel sein, wenn C++ 0x einige Tools für das Problem haben wird. Ich werde C++ 0x Entwurf überprüfen. – bayda

+0

Vielleicht könnte der Compiler es überprüfen und eine Warnung ausgeben, dass ein Mitglied nicht kopiert wird ... aber dann, wie würdest du sagen, dass dir ein Mitglied egal ist ... –

1

Fügen Sie diese Funktionalität zu Ihrem Komponententest hinzu. Wenn Ihr Komponententest die Serialisierung/Deserialisierung abdeckt (z. B. indem Sie sicherstellen, dass deser(ser(x)) == x), Fehler beim Hinzufügen von Mitgliedern der Serialisierungsfunktion während des Komponententests fehlschlagen. Dasselbe könnte für Kopierwerkzeuge funktionieren.

Es ist nicht so ideal wie Kompilierzeit Fehler, aber wenn Sie eine gute Unit-Test-Framework an Ort und Stelle haben, und Sie sicherstellen, dass Sie eine angemessene Abdeckung haben, dann diese Fehler der Vernachlässigung wäre schwieriger zu machen.

+1

Danke für die Antwort. Im Allgemeinen: Unit Testing - nette Sache, und ich dachte über die Kontrolle mit Unit-Tests nach. Aber wir können vergessen, add member zu operator == und assert (deserialize (serialize (x)) == x) oder 'y = x; behaupten (y == x); wird ok, wenn wir in einigen der verwendeten Funktionen Add Member vergessen. – bayda

0

Ich denke, der beste Weg, um dieses Problem zu vermeiden, ist es im Stamm geschnitten: Verwenden Sie keine benutzerdefinierten Kopie Operator/Konstruktor.

Dies ist nicht immer möglich, aber in den meisten Fällen glaube ich wirklich, es ist ...

Verwandte Themen