2016-09-15 5 views
0

Ich schreibe gerade C-Code in C++ - Code um. Dabei ersetze ich structs durch classes. Das bedeutet, dass einige der Variablen von öffentlich zu privat gehen. Jetzt während der Übergangsphase möchte ich eine Fehlerüberprüfung durchführen, indem ich das Programm manchmal kompiliere und ausführe. So beabsichtigte ich, öffentliche und private Variablen gleichzeitig zu haben, die verbunden sind, d.h. wenn ich etwas in die private Variable schreibe, ändert sich auch die öffentliche Variable. Nichtsdestoweniger möchte ich nur in die privaten Variablen schreiben, indem ich separate Funktionen verwende, d. H. Die öffentlichen Variablen als schreibgeschützte Variablen haben. Mein aktueller Ansatz ist:Öffentliche und private Variablen verknüpfen (mit Schreibzugriff auf private Variablen)

#include <iostream> 
#include <stdio.h> 

class test_vec 
{ 
    private: 
     int x, y; 
     int data[2]; 
    public: 
     int x_ext, y_ext; 
     int data_ext[2]; 

     test_vec(int x, int y) 
     { 
      this->x = x; 
      this->y = y; 
      this->x_ext = this->x; 
      this->y_ext = this->y; 
     } 

     ~test_vec() 
     {} 

     void set_x(int x) 
     { 
      this->x = x; 
     } 

     void set_y(int y) 
     { 
      this->y = y; 
     } 
}; 

int main(void) 
{ 
    std::cout << "Hello World\n"; 
    test_vec test(1, 2); 
    printf("test has the properties (%d, %d)\n", test.x_ext, test.y_ext);//So far, so good 
    test.set_x(4); 
    test.set_y(10); 
    printf("test has the properties (%d, %d)\n", test.x_ext, test.y_ext);//Not updated! 
    return 0; 
} 

Wie kann ich die Verknüpfungen zwischen den Variablen ändern? Im Moment habe ich bereits zwei ineinander kopierte Zeiger, aber wie kann ich die externe Variable auf die interne Variable "sperren"?

+0

Da Sie Client-Code ändern müssen, um den neuen Namen trotzdem zu verwenden ('_ext' hinzufügen), warum ändern Sie es einfach nicht, um einen Getter zu verwenden? Das Speichern von Const-Referenzen macht Ihr Objekt größer und sieht ehrlich komisch aus. – Useless

+2

Terminologie nitpick: Es macht keinen Sinn über "Strukturen mit Klassen zu ersetzen", da es keinen Unterschied zwischen "struct" und "class" gibt, außer dem Standardzugriff von Mitgliedern, und Sie machen das mit 'private:' als erste Zeile in Ihrer Klasse. – hyde

+0

@Useless: Sie werden in einer endgültigen Bereinigung entfernt, aber bis dahin würde ich sie lieber haben, um das Programm während der Übergangsphase testen zu können. –

Antwort

4

Nicht sicher, ob es ein gutes Design-Muster ist seit Inline-Getter schnell, aber man könnte ständige Verweise auf Ihre privaten Variablen erstellen:

class test_vec 
{ 
    private: 
     int x, y; 
     int data[2]; 
    public: 
     const int &x_ext, &y_ext; 
     int data_ext[2]; 

     // you have to initialize the references before constructor body 
     // references cannot be let uninitialized 
     test_vec(int x, int y) : x_ext(this->x), y_ext(this->y) 
     { 
      this->x = x; 
      this->y = y; 

     } 

     ~test_vec() 
     {} 

     inline void set_x(int x) 
     { 
      this->x = x; 
     } 

     inline void set_y(int y) 
     { 
      this->y = y; 
     } 
}; 

wenn x oder y ändert x_ext und y_ext folgen:

Hello World 
test has the properties (1, 2) 
test has the properties (4, 10) 

Bonus: Konstante Referenzen können nicht geändert werden. Das ist die nächste Sache einer Leseeigenschaft, die Sie hier bekommen haben :)

Wenn Sie diese Einschränkung nicht möchten, entfernen Sie einfach die const Qualifier, aber da Sie ermutigen, jetzt, dass Sie C++ haben, würde ich es wie lassen ist und lassen Sie die Autoren schlagen die Wand auf die (nicht zu erwähnen, eine gute sed/Regex Ersatz könnte alle Ihre Schreibvorgänge automatisch umgestalten)

+0

Sie sollten auch erwähnen, wie die öffentlichen Referenzen jetzt "schreibgeschützt" sind, weil Sie sie const. – Hayt

+0

@ Hayt: Das interessiert mich nicht, das war afaik auch in der Frage geschrieben .. –

+0

@arc_lupus Während es dir egal ist, ist dies eine Veränderung (und auch ein Vorteil) dieser Herangehensweise und könnte etwas für andere sein, die darüber stolpern ein ähnliches Problem und lies diese Antwort. – Hayt

1

Sie können Referenzen für diese Zwecke verwenden.

Sagen Sie bitte diese Einstellung haben:

myclass c(33, 12.3f); 

c.set_a(12); 
c.set_b(111.1f); 

//This... 
std::cout<<c.ref_to_a<<" "<<c.ref_to_b<<std::endl; 
//Should be the same as this... 
std::cout<<c.get_a()<<" "<<c.get_b()<<std::endl; 

Beachten Sie die Zugriffseinstellungen: die Verweise sind öffentlich, Sie schreiben und von ihnen lesen bedeutet

class myclass{ 

    public: 

       myclass(int pa, float pb); 

    int   get_a() const {return a;} 
    float   get_b() const {return b;} 

    void   set_a(int v) {a=v;} 
    void   set_b(float v) {b=v;} 

    private: 
    //These are the real values, private 
    int   a; 
    float   b; 

    public: 
    //These are the references, public 
    int&   ref_to_a; 
    float&   ref_to_b;   
} 

myclass::myclass(int pa, float pb) 
    :a(pa), b(pb), ref_to_a(a), ref_to_b(b) 
{ 

} 

Sie weitergehen kann. Wenn Sie möchten, dass sie nur gelesen werden, können Sie mit der Konstanz spielen.

1

Ich würde nicht stören. Machen Sie die Mitglieder nur für den Moment öffentlich, und wenn Sie alle externen Referenzen korrigiert haben, machen Sie sie privat.

class test_vec 
{ 
    public: // For now. Will become private later 
     int x, y; 
    public: // For now. 
     int data[2]; 
    public: // For ever 
     test_vec(int x, int y) 
      : x(x), y(y) // Prefer initialization to assignment. 
     { 
     } 

     ~test_vec() 
     {} 

     void set_x(int x) 
     { 
      this->x = x; 
     } 
     void set_y(int y) 
     { 
      this->y = y; 
     } 

     int get_x() const { return x; } // etc 
}; 

Wenn Sie wollte wirklich, könnten Sie x_ext sein ein Verweis auf const machen - aber es ist viel mehr idiomatische in C++ zu Getter Funktionen sein zu lassen.

class test_vec 
{ 
    private: 
     int x, y; 
     int data[2]; 
    public: 
     int const& x_ext; 
     int const& y_ext; 

     test_vec(int x_, int y_) 
      : x(x_), y(y_) 
      , x_ext(x), y_ext(y) // You *have* to use initialization here. 
     { 
     } 

     ~test_vec() 
     {} 

     void set_x(int x) 
     { 
      this->x = x; 
     } 
     void set_y(int y) 
     { 
      this->y = y; 
     } 
}; 
Verwandte Themen