Es ist nicht möglich const Member einer Klasse zu deklarieren die nicht statisch sind ??



  • @Sebastian
    =)Das habe ich schon herausgehört. Aber es ist mir zu kompliziert jetzt die zusammenhänge zu erklären. Grundsatzdiskussionen sind gerade zu langwierig. Des weiteren kommt meißt was dabei raus, was garnicht so funktioniert wie ich es gerne hätte. Ich benötige das, was ich beschrieben habe.

    @Tachyon
    Das geht leider nicht. Des weiteren müßte ich dann den Allocator überschreiben.
    Gruß



  • AlexXXx schrieb:

    @Tachyon
    Das geht leider nicht. Des weiteren müßte ich dann den Allocator überschreiben.
    Gruß

    Äh WAS? Allokator überschreiben?
    Vielleicht erklärst Du uns mal, was Der Code genau machen soll und nicht, wie Du versuchst es zu codieren.



  • @Sebastian
    Sorry habe deine Antwort nciht genau genug gelesen.
    Private wird das Array so oder so werden. Weiß gerade nicht was es ist, aber
    ich werde es in keinen Fall public machen.
    Ich möchte aber nicht den Anwender meiner klasse davor bewahren auf mein array zu zu greifen, sonder mich, solange ich Methoden der klasse schreibe, welche auf diese Array zugreifen.
    Und das soll bitte der compiler machen, damit ich nicht so viel debuggen muß.
    Es geht auch ohne. Aber es ist schöner wenn mir der kompiler sagt, Alex du hast den Zugriff verplant. Drink einen kaffee!!!!
    Gruß
    P.s.: Ich hätte gerne eine Abkürtzung mit Blümchen und nem See an der seite 🙂
    (Nicht ernst gemeint aber wenn du schon so Bildhaft schreibst komm ich ins träumen sebastian)



  • AlexXXx schrieb:

    Das habe ich schon herausgehört. Aber es ist mir zu kompliziert jetzt die zusammenhänge zu erklären. Grundsatzdiskussionen sind gerade zu langwierig. Des weiteren kommt meißt was dabei raus, was garnicht so funktioniert wie ich es gerne hätte. Ich benötige das, was ich beschrieben habe.

    Na, dann sieh mal zu, wie du es allein herausfindet. Mit jedenfalls ist es viel zu kompliziert, deinen Gedankengängen zu folgen.

    Stefan.



  • Laut Breymann:

    Klassenspezifische Variablen müssen außerhalb der Klassendefinition definiert und initialisiert werden. Dies gilt nicht für klassenspezifische Konstanten, für die der Compiler keinen Platz anlegen muß, weil er direkt ihren Wert einsetzten kann. In C++ ist die Ausnahme jedoch auf integrale und Aufzählungstypen beschränkt

    Damit gibt es (lt.Breymann) ist keine Möglichkeit ein konstantes Klassenspezifisches Array zu konstruieren.



  • @DStefan
    Sorry. Ist blöd ausgedrückt. Danke dir für Hilfe bis dahin
    Gruß



  • @DeepCopy
    Klassenspezifisch meint nicht static ??
    Also eine Variable mit welcher man z.B. die Instanzen (nicht STL Sinn)
    einer Klasse zählen würde.
    Ich brächte eine Membervariable die const ist.
    Gruß



  • AlexXXx schrieb:

    @DeepCopy
    Klassenspezifisch meint nicht static ??

    Doch, static ist das was hier als "Klassenspezifisch" (im Gegensatz zu Objektspezifisch) bezeichniet wird.

    Ich brächte eine Membervariable die const ist.

    Ein normales Member? also ein Array pro Objekt oder eins für alle Objekte zusammen? Auch wenn es für dich noch so umständlich ist, versuch bitte zu beschreiben was du erreichen willst. Genau so wie du es machen wolltest gehts ja offenbar nicht, das hast du (bzw. dein Compiler) ja schon selber herausgefunden. Wir können dir aber nur Alternativen vorschlagen wenn wir wissen, was du erreichen willst, um eben herauszufinden ob die Alternativen auch das tun was du brauchst.

    AlexXXx schrieb:

    Grundsatzdiskussionen sind gerade zu langwierig. Des weiteren kommt meißt was dabei raus, was garnicht so funktioniert wie ich es gerne hätte.

    Genau in so einer Grundsatzdiskussion stecken wir gerade, weil du ein Geheimnis aus deinen Zielen machst und uns nicht verrätst wie du es denn gern hättest. (Sondern nur was du gerne hättest, und das gibts nicht, zumindest nicht in C++)



  • Dazu Breymann

    Auch wenn das Schlüsselwort static fehlt, sind sie für alle Objekte einer Klasse gleich, also klassen- und nicht objektspezifisch

    Damit gibt es keine konstanten Klassen-Elemente (Member) - eins für jedes Objekt.



  • AlexXXx schrieb:

    @DStefan
    Sorry. Ist blöd ausgedrückt. Danke dir für Hilfe bis dahin
    Gruß

    Schon OK.

    Bitte überlege dir mal folgendes:

    - Brauche ich eine Klassen- oder eine Objekt-Konstante (hat pumuckl schon gefragt)?

    - Brauche ich diese Konstante nur innerhalb der Klasse (private) oder muss es einen Zugriff von außen geben (public oder protected)?

    - Muss dies im C++-Sinn eine Konstante sein (also mit reichlich const im Namen) oder muss nur ein Zugriff gewährleistet sein, der nichts verändern kann?

    Ich denke, die letzte Frage wirst du wohl mit ja beantworten können. Was ist mit den andren Fragen? Und vielleicht solltest du dir mal die bisher gezeigten Lösungsvorschläge ansehen und dich fragen, ob einer der Vorschläge zu deinen Anforderungen passt. Falls nein, was gefällt dir nicht?

    Stefan.



  • DeepCopy schrieb:

    Dazu Breymann

    Auch wenn das Schlüsselwort static fehlt, sind sie für alle Objekte einer Klasse gleich, also klassen- und nicht objektspezifisch

    Damit gibt es keine konstanten Klassen-Elemente (Member) - eins für jedes Objekt.

    Doch gibt es:

    struct Test
    {
       Test(int a): m_a(a){}
       int const m_a;
    };
    
    Test t1(3);
    Test t2(42);
    
    std::cout << t1.m_a << '\n'; // 3
    std::cout << t2.m_a << '\n'; // 42
    

    Ich kann mir auch nicht vorstellen, das Breymann das so geschrieben hat.


  • Mod

    1. Nicht-statische konstante Datenmember einer Klasse sind (ebnso wie Referenzen, bei denen noch andere Gründe dazukommen) nur äußerst selten gerechtfertigt. Häufig werden diese Member irrtümölich nur deshalb als const deklariert, weil geplant ist, die Klasse selbst nur mit const-Objekten zu verwenden. Das ist kein ausreichender Grund, ein mechanisches const-Hinschreiben, nur weil man es kann, ist auch nicht geeignet, Fehler zu vermeiden.
    Ausschlaggebend sollte vielmehr sein, ob die const-Eigenschaft das Members, unabhängig davon besteht, ob das Objekt, zu dem es gehört const ist oder nicht. Nach meiner Erkenntnis ist das nur selten der Fall - prototypisch gilt es z.B. für Proxyobjekte.

    2. Es ist mit dem gegenwärtigen Standard nicht möglich, nichtstatische Arraymember in der Ctor-Initialisierungsliste zu initialisieren (außer Defaultinitialisierung). Weil nichtstatische const-Member aber stets dort initialisiert werden müssen, sind Klassen mit nichtstatischen konstanten rraymembern praktisch nicht verwendbar. Eine Ausnahme besteht lediglich im Falle von Aggregaten, die per Aggregat-Initialiserungsliste initialisiert werden können (auf diese Weise könnte man das Array doch wieder initialisieren, wenn man es in eine eigene Klasse verpackt, ich sehe darin allerdings wenig Sinn).

    struct arrayholder
    {
        const int x[3];
    }
    class foo
    {
    ...
        arrayholder arr;
        foo() : arr(get_arr() /* hier RVO */) { ... }
        arrayholder get_arr() { arrayholder x = { 0, 1, 2 }; return arr; /*hier NRVO */ }
        ...
    }
    


  • Okay. Danke.
    Das es das nicht gibt hat mir viel weiter geholfen.
    Dann passe ich selber auf meine Zugriffe auf.
    Es ist nichts zwingendes, hatte lediglich gehofft der compiler würde mir die Arbeit abnehmen.
    Bei mir ist
    Klassenvariable = KLassenspezifisch
    Membervariable = Objektspezifisch.
    Also in eure Worten müßte es glaube ich heißen
    -Ich benötige ein Zweidimensionales char array,
    dessen zweite Dimension dynamisch angefordert werden muß.
    -Das Zweidimensionale Array soll objektspezifisch sein.
    -Die Größe des dynamisch angeforderten Speichers darf nur in Ausnahmefällen verändert werden. Muß an sonsten aber immer konstanst sein. Ausnahme fall meint, dass ich es explizit machen können muß. Also Mit new und delete, da diese Operatoren bei mit überschrieben sind.
    -Die pointer der dynamisch angeforderten char arrays(nicht der Inhalt) würde ich jetzt gerne const machen, um zu vermeiden, dass ich, während ich memberfunktionen schreibe, welche auf die Arrays zugreifen nicht den Pointer verändere, und damit Speicherzugriffsfehler verursache oder speicherlöcher erzeuge. Die Zugriffprüfung wäre dann eben während des compilierens, und nicht während der Programmlaufzeit was für mcih besser wäre.

    Soweit ich das jetzt mitbekomen habe gibt es das aber nicht.
    Es ist auch immer eine Frage zwischen aufwand und nutzen. Das Programm an sich wird sich dadurch const nicht ändern. Lediglich wann der fehler entdeckt wird.

    Gruß



  • pumuckl schrieb:

    AlexXXx schrieb:

    Grundsatzdiskussionen sind gerade zu langwierig. Des weiteren kommt meißt was dabei raus, was garnicht so funktioniert wie ich es gerne hätte.

    Genau in so einer Grundsatzdiskussion stecken wir gerade, weil du ein Geheimnis aus deinen Zielen machst und uns nicht verrätst wie du es denn gern hättest. (Sondern nur was du gerne hättest, und das gibts nicht, zumindest nicht in C++)

    Genau. Lustig, wenn man mit seinem Versuch gerade das erreicht, was man unbedingt vermeiden wollte. 😉

    AlexXXx schrieb:

    @Nexus
    Deine Idee hört sich gut an, aber ich verstehe sie nicht.

    Ich hatte ursprünglich sowas gemeint, aber bin mir nicht sicher, ob das noch auf dein Problem zutrifft:

    class MyClass
    {
        public:
            MyClass()
            : MyArray(CreateArray())
            {
            }
    
        private:
            std::tr1::array<Irgendwas, Anzahl> CreateArray() const;
    
        private:
            const std::tr1::array<Irgendwas, Anzahl> MyArray;
    };
    

    AlexXXx schrieb:

    Also in eure Worten müßte es glaube ich heißen
    -Ich benötige ein Zweidimensionales char array,
    dessen zweite Dimension dynamisch angefordert werden muß.

    Vielleicht sowas wie std::tr1::array<std::vector<Irgendwas>, Anzahl> ? Zumindest würde ich Zugriffe per new und delete auf jeden Fall kapseln.

    *Edit: Zweiter Templateparameter bei std::tr1::array *



  • @Camper
    Wow.
    Danke für geniale Antwort 🙂
    Den Quelltext werde ich mir Kopieren und merken. Für meine Klasse ist
    der Aufwand aber nicht gerechtfertigt. Aber genau das bräuchte ich.

    Gruß Alex



  • Member mit const char*[3] anlegen. Im Constructor fuer jeden Eintrag neuen Speicher anfordern und mittels const_cast, das const entfernen. Zuweisen ... (so in etwa). Ich halte das Vorgehen trotzdem fuer fragwuerdig aber C++ verbietet dir fuer gewoehnlich nichts.



  • knivil schrieb:

    Im Constructor fuer jeden Eintrag neuen Speicher anfordern und mittels const_cast, das const entfernen. Zuweisen ... (so in etwa). Ich halte das Vorgehen trotzdem fuer fragwuerdig aber C++ verbietet dir fuer gewoehnlich nichts.

    Das ist dennoch kein Grund, undefiniertes Verhalten zu riskieren, gerade wenn es schönere Möglichkeiten gibt.



  • @Nexus
    Danke für Antwort. Ich mußte erst recherchieren um folgen u können.
    std::tr1::array war mit bis jetzt unbekannt.
    Das müßte auch hin hauen.

    Gruß 🙂


  • Mod

    AlexXXx schrieb:

    @Camper
    Wow.
    Danke für geniale Antwort 🙂
    Den Quelltext werde ich mir Kopieren und merken. Für meine Klasse ist
    der Aufwand aber nicht gerechtfertigt. Aber genau das bräuchte ich.

    Gruß Alex

    Beachte aber, dass ich im Quelltext etwas gemacht habe, wogegen ich darüber argumentiert habe. Besser wäre sicherlich, x in arrayholder nicht-const zu halten, während arr (für das man z.B. noch op[] überladen könnte) in foo const sein sollte.

    tr1::array ist im Grunde so ein Arrayholder, nur noch etwas weiter aufgebohrt.



  • Tachyon schrieb:

    Ich kann mir auch nicht vorstellen, das Breymann das so geschrieben hat.

    Doch hat er:
    Ullrich Breymann C++ eine Einführung (5.aktualisierte und erweiterte Auflage)
    Kap 7.2.1 Klassenspezifische Konstante

    Klassenspezifische Variable müssen außerhalb der Klassendefinition definiert und inititalisiert werden. Dies gilt nicht für klassenspezifische Konstanten, für die der Compiler keinen Platz anlegen muss, weil er direkt ihren Wert einsetzen kann, In C++ ist diese Ausnahme jedoch auf integrale und Aufzählungstypen beschränkt:

    class KlasseMitKonstanten
    {
      enum RGB {rot = 0x0001, gelb = 0x0002, blau = 0x0004 };
      static const unsigned int maximaleAnzahl = 1000;
      // Verwendung zum Beispiel:
      static int CArray[maximaleAnzahl];
      // ...
    

    Diese Konstanten werden innerhalb der Klassendefinition initialisiert. Auch wenn das Schlüsselwort static fehlt (siehe enum), sind sie für alle Objekte einer Klasse gleich, also klassen- und nicht objektspezifisch

    Ende des Kapitels.

    Aber in seiner neuen Auflage leicht geändert und bei GoogleBooks lesbar Ullrich Breymann C++ eine Einführung

    Ich glaub ich brauch mal ein neues C++Buch...


Anmelden zum Antworten