Was ist besser: No Copy/No Assignment Basisklasse oder Makro



  • Hey volkad,

    warum eigentlich "typedef int _noCopy"? Käme

    #define NOCOPY

    nicht auf das Gleiche raus?

    @devil: Das sollte doch gar nicht als Basisklasse gedacht sein?!?



  • prob schrieb:

    warum eigentlich "typedef int _noCopy"? Käme

    #define NOCOPY

    nicht auf das Gleiche raus?

    Dann hättest du einen ; mitten in der KLassendefinition stehen...

    @devil: Das sollte doch gar nicht als Basisklasse gedacht sein?!?

    Natürlich keine Basisklasse, sondern Member.

    Sobald ein Member nicht Copyable ist, kann der Compiler keine Default Aktionen mehr erstellen.



  • prob schrieb:

    Hey volkad,
    warum eigentlich "typedef int _noCopy"? Käme
    #define NOCOPY
    nicht auf das Gleiche raus?
    @devil: Das sollte doch gar nicht als Basisklasse gedacht sein?!?

    eigentlich sollte ich das als rätsel stehen lassen. 😃
    .
    .
    .
    spoiler
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    meine makros dürfen immer mit abschließendem semikolon geschrieben werden. das ist manchmal wichtig, wie bei

    //schlechtes assert
    #ifndef NDEBUG
       #define ASSERT(x) if(!x) throw "fehler";
    #else
       #define ASSERT(x)
    #endif
    
    ASSERT(sizeof(int)==4)//klappt wurnderbar
    
    if(bar)
       if(foo)
          ASSERT(false)//aua!
       else
          cout<<"seltsam";
    

    aber auch
    if(bar)
    if(foo)
    ASSERT(false);//aua!
    else
    cout<<"seltsam";
    [/cpp]
    das führt zur generellen forderung, daß makros nie ein semikolon am ende einbringen. also mindestens mal

    //schlechtes assert
    #ifndef NDEBUG
       #define ASSERT(x) if(!x) throw "fehler"
    #else
       #define ASSERT(x)
    #endif
    
    ASSERT(sizeof(int)==4);//klappt wurnderbar
    
    if(bar)
       if(foo)
          ASSERT(false);// aua?
       else
          cout<<"seltsam";
    

    naja, das aua? tut auch noch weh. das else drunter bindet im debug-mode das if aus dem makro und im release-mode das if(foo).
    also

    #ifndef NDEBUG
       #define ASSERT(x) if(x);else throw "fehler"
    #else
       #define ASSERT(x)
    #endif
    

    und wenn man sich angewöhnt, daß makros generell nicht ihr eigenes semikolon einbringen, daß man aber immer ein semikolon am ende setzen darf, muß es bei NOCOPY geeignet abgefackelt werden. ein alleinstehendes semikolon innerhalb der klasse ist nach c++-standard verböten. daher das typedef.



  • und wenn man if(false){}else foo
    statt if(false);else foo
    schreibt - kann man auch einige Compilerwarnungen umgehen 🙂



  • MaSTaH schrieb:

    Nein, das würde in der Verantwortung des Programmierers liegen. Oder das Makro muss die Section nachher wieder zurücksetzen. Aber worauf? public oder protected? Aber wie gesagt... das Makro war im wahrsten Sinne eine "Schnapsidee"!

    public:
        DENY_COPY(Foo); // "private:" enthalten
        Foo(); // Foo ist nicht mehr public, sieht aber keiner
    

    doch, ganz zum schluss kommt ein nettes public, lieber MaSTaH, lesen lernen :p

    @Volkard gute idee, aber leider auch wieder gut auszuhebeln 😞



  • otze schrieb:

    @Volkard gute idee, aber leider auch wieder gut auszuhebeln 😞

    kann sein. mit ein wenig krimineler energie kriegt man alles kurz und klein.
    ich erinnere mal an den entprivatisierer:

    class Foo{
    private int x;
    ...
    };
    int getPrivateX(Foo& f){
    class Bar{
    public int x;
    };
    return ((Bar*)&foo).x;
    }

    aber NoCopy seztze ich seit jahren ein und es ist angenehm.



  • otze schrieb:

    doch, ganz zum schluss kommt ein nettes public, lieber MaSTaH, lesen lernen :p

    Ok, dann folgender Fall...

    protected:
        DENY_COPY(Foo);
        Foo(); // Foo ist public, aber beim lesen des Codes denkst du es sei protected.
    

    Ich wollte dich nur darauf aufmerksam machen, dass man bei deiner Variante aufpassen muss. Es kann u.U. den Benutzer verwirren.



  • otze schrieb:

    @Volkard gute idee, aber leider auch wieder gut auszuhebeln 😞

    Wie denn?
    Ich meine jetzt: wie kann man es aushebeln ohne es zu bemerken?

    Ich kann ja immer notfalls ein
    #define private public

    machen und so alles knacken 🙂 oder direkt den Code ändern...



  • MaSTaH schrieb:

    Ich wollte dich nur darauf aufmerksam machen, dass man bei deiner Variante aufpassen muss. Es kann u.U. den Benutzer verwirren.

    haut man meine variante in die private-sektion, gibs nen erwünschen compilerfehler.
    haut man sie aus versehen in die public-section gips halt nen linkerfehler.
    mehr gefahren sehe ich nicht. welche meinst du?



  • volkard: Das war nicht auf deine, sondern auf otzes Idee bezogen. Er hatte so etwas in der Art gepostet...

    #define FOO(x) private: /* was auch immer */ public:
    

    Das finde ich generell nicht schön, da es den Code verwirrend machen kann wenn es falsch benutzt wird (in protected- oder private-Abschnitt). Vom bloßen drüberlesen denkt man, man sei noch in einem private/protected-Abschnitt, aber das Makro hat ihn auf public umgestellt. Man muss also dem Programmierer, der es verwenden soll beibringen, dass er das Ding nur in einem public-Abschnitt verwenden darf. Was spricht dann dagegen sich die Umstellungen zu sparen und den Programmierer anzuweisen das Makro in dem private-Abschnitt zu benutzen?


Anmelden zum Antworten