Eigenschaft - Methode - return?


  • Mod

    Selbst wenn es hier wirklich einen guten Grund für C-Strings gäbe (welche übrigens nicht gut mit Referenzen mischen), so hast du dir doch selber schon korrekt erklärt, wieso das nicht funktioniert. Beim ersten Beispiel: Welchen Typ braucht man zur Initialisierung einer char&, welchen Typ hat der Ausdruck? Beim zweiten Beispiel: Gleiche Frage, mit den entsprechenden Typen aus dem zweiten Beispiel.



  • asfdlol schrieb:

    super beispiel um aufzuzeigen wieso c-strings und c-arrays quatsch sind.

    kannst du deinen code hier bitte mit std::string und mit std::array / std::vector nachimplementieren?

    inline, (void), scheint recht alter Stoff zu sein.

    "c-strings und c-arrays" klingt danach, als seien die aus einer anderen sprache, was natürlich quatsch ist. sie haben sehr wohl ihre berechtigung in c++. nur vielleicht nicht gerade als dateinanemsliste.
    in der tat ist hier vector<string> möglicherweise ein klein wenig übersichtlicher.

    char (&getfile())[30][260] { return file; }
    	char (*getfile())[260] { return file; }
    	vector<string>& { return file; }
    

  • Mod

    super beispiel um aufzuzeigen wieso c-strings und c-arrays quatsch sind.

    Das ist einfach unglaublich. Du bekommst im Forum reingelabert, dass alles aus C Verdammnis bringt, und verbreitest nun die Kunde.

    Edit: Hat volkard schon gesagt.



  • Arcoth schrieb:

    super beispiel um aufzuzeigen wieso c-strings und c-arrays quatsch sind.

    Jetzt haltet doch mal alle die Schnauze. Hier wird permament gesülzt, dass alles "aus C" böse ist und Verdammnis bereitet... 👎

    jap, weil eine liste mit einer fixen anzahl an dateien mit einer fixen anzahl an buchstaben ja auch so sinnig ist! wie dumm von mir...



  • Gargamel12 schrieb:

    geht irgendwie nicht.

    public:
    inline char& getfile(void) { return file; }
    inline char& getdir(void){ return dir; }
    
    private:
    char file [30][260];
    char dir [30][260];
    

    typedef hilft bei sowas gerne mal.

    #include <iostream>
    using namespace std;
    
    typedef char Name[260];
    
    class Test
    {
    	public:
    	inline Name* getfile(void) { return file; }
    	inline Name* getdir(void){ return dir; }
    
    	private:
    	Name file [30];
    	Name dir [30];
    };
    
    int main(){
    }
    

  • Mod

    Der Grund, warum ein Zeiger auf einen Zeiger als Funktionsrückgabewert nicht funktioniert, ist übrigens folgender:
    Ein zweidimesionales Array ist ein Array von Objekten die Arrays sind. Ein Array kann auf einen Zeiger auf das erste Element zerfallen, aber das erste Element hat Typ char[260] , nicht char* . Daher kann es nicht auf einen Zeiger auf char* , sondern nur auf einen Zeiger auf char[260] zerfallen.

    asfdlol schrieb:

    jap, weil eine liste mit einer fixen anzahl an dateien mit einer fixen anzahl an buchstaben ja auch so sinnig ist! wie dumm von mir...

    Darum geht es nicht. Du redest davon, als ob es generell Quatsch ist. Das ist völlig falsch. Es eignet sich hier einfach nicht, punkt. Das heißt bei weitem nicht, das C-Arrays Quatsch sind.

    Denkst du, ich renne herum und erkläre jedem, der eine std::list als ein Array benutzt, "Super Beispiel dafür, das std::list Quatsch ist!"?



  • Arcoth schrieb:

    Denkst du, ich renne herum und erkläre jedem, der eine std::list als sequentielle Container benutzt, "Super Beispiel dafür, das std::list Quatsch ist!"?

    Aber std::list ist doch Quatsch, oder? Hab das wenigstens all die Jahre jedem erzählt. 🙄
    Ach nee, ich hatte nur jedem verraten, daß ich selber sie niemals verwende.



  • Arcoth schrieb:

    völlig falsch. Es eignet sich hier einfach nicht, punkt. Das heißt bei weitem nicht, das C-Arrays Quatsch sind.

    okay, einerseits sind c-arrays nicht pauschal quatsch, das nehme ich zurück. ich hätte es auf genau diesen anwendungsfall spezifizieren sollen.
    andererseits verstehe ich dennoch nicht wieso man anstatt eines std::array's ein c-array nutzen sollte. c-arrays haben die tendenz unintuitiv zu sein.

    Arcoth schrieb:

    Denkst du, ich renne herum und erkläre jedem, der eine std::list als ein Array benutzt, "Super Beispiel dafür, das std::list Quatsch ist!"?

    das ist an den haaren herbeigezogen. in diesem thread hat es durchaus zusammenhang mit der frage (sonst hätte ich mir meinen kommentar gespart). der op hat probleme mit den typen und daran schuld ist meiner auffassung nach in erster linie das mit den arrays.


  • Mod

    @volkard: Ja, Du magst nur provozieren. Schade.

    in diesem thread hat es durchaus zusammenhang mit der frage

    Welcher Frage? Die Frage war, wie er es zum Laufen bekommt. Das hat der Volki schon gesagt. Deine Antwort war "Super Beispiel dafür, dass A und B quatsch sind".

    der op hat probleme mit den typen und daran schuld ist meiner auffassung nach in erster linie das mit den arrays.

    Gut, das stimmt. Aber dann hättest du das völlig anders formulieren müssen. Vor allem nicht so pauschal.
    Ich will auch nicht wieder spitzfindig werden 🙂 , sowas ist nur einfach daneben, weil alle im Folgenden Schiss haben, ihre Finger an ein "C-Array" zu legen. Ein einfaches "Hier eignet sich std::vector<>" o.ä. tut es auch. Du bist so ein extremer Idealist, der alles extrem generisch und modern programmieren will.

    andererseits verstehe ich dennoch nicht wieso man anstatt eines std::array's ein c-array nutzen sollte. c-arrays haben die tendenz unintuitiv zu sein.

    Da hast du Recht. Bspw. kein C++11 ist ein Grund.



  • Vielen Dank für die zahlreichen Antworten und die Erklärung von Arcoth wieso man keine doppelten Zeiger übergeben kann.

    volkard schrieb:

    #include <iostream>
    using namespace std;
    
    typedef char Name[260];
    
    class Test
    {
    	public:
    	inline Name* getfile(void) { return file; }
    	inline Name* getdir(void){ return dir; }
    
    	private:
    	Name file [30];
    	Name dir [30];
    };
    
    int main(){
    }
    

    Zu diesem Code hätte ich jedoch noch eine Frage, und zwar verstehe ich nicht ganz was durch den Einsatz von typdef erreicht wird? Kann das ganze auch ohne typdef geschreiben werden ?

    Und zum Schluss wäre noch die erste Frage ob das ganze über Referenz zu übergeben möglich ist?

    Vielen Dank!

    Und schöne Grüße



  • Gargamel12 schrieb:

    Zu diesem Code hätte ich jedoch noch eine Frage, und zwar verstehe ich nicht ganz was durch den Einsatz von typdef erreicht wird?

    int baum;
    sagt "es gibt ab jetzt eine neue Variable, sie heißt Baum und ist ein int".

    typedef int Baum;
    sagt "es gibt ab jetzt einen neuen Typ, er heißt Baum und ist ein int".
    Ich kann ab jetzt "Baum a" statt "int a" schreiben.

    char name[260];
    sagt "es gibt ab jetzt ein neue Variable, sie heißt Name und ist ein Array mit 260 Zeichen".

    typedef char Name[260];
    sagt "es gibt ab jetzt einn neuen Typ, er heißt Name und ist ein Array mit 260 Zeichen".
    Ich kann ab jetzt "Name a" statt "char a[260]" schreiben.

    Und hier wird klar, was es bringt: die komische Regelung bei "char a[260]", daß der Typ von a links UND rechts von a hingeschrieben werden muss, wird umgangen.

    Gargamel12 schrieb:

    Kann das ganze auch ohne typdef geschreiben werden ?

    Klar. Aber dann wird aus

    Name* getfile()
    

    ein

    char (*getfile())[260]
    

    Gargamel12 schrieb:

    Und zum Schluss wäre noch die erste Frage ob das ganze über Referenz zu übergeben möglich ist?

    Geht auch.

    Also alle drei Zeilen gehen:

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    typedef char Name[260];
    
    class Test
    {
    	public:
    	char (&getfile())[30][260] { return file; }//per Referenz
    //	char (*getfile())[260] { return file; }//per Zeiger auf char[260]
    //	Name* getfile() { return file; }//per Zeiger auf Name (also ebenfalls auf char[260])
    
    	public:
    	Name file [30];
    };
    
    int main(){
    	Test t;
    	strcpy(t.file[5],"c:/autoexec.bat");
    	cout<<t.getfile()[5]<<'\n';
    }
    

    So, und wie kommt man auf "char (*getfile())[260]"? Nur, wenn man Typen lesen kann! Das Typenlesen sieht viel schlimmer aus als es ist.

    Statt wie auch empfohlen vor der Syntax zu fliehen (und vector<string> zu nehmen, weil es einfacher zu lesen ist), wäre es meiner Meinung nach besser, sie jetzt zu erlernen (aber bald Umsteigen, vector<string> ist nämlich trotzdem viel angemessener):

    Hol Dir einen Kaffe und setz Dich auf einen erdbebensicheren Stuhl, gleich kommen sehr anstrengende fünf Minuten auf Dich zu.

    ~
    ~
    ~
    (Pausenmusik)
    ~
    ~
    ~
    (Pausenmusik)
    ~
    ~
    ~
    (Pausenmusik)
    ~
    ~
    ~

    Man fängt beim Bezeicher an zu lesen und sagt "Bezeichner ist ein" und liest dann, wenn es möglich ist nach rechts, und wenn rechts nichts mehr steht nach links.

    int a;//a ist ein int

    int const a;//a ist ein konstanter int

    int * a;//a ist ein zeiger auf int

    int a[5];//a ist ein Array mit 5 ints

    (Zur Erinnerung: rechts vor links lesen.)
    int *a[5];//a ist ein Array mit 5 Zeigern auf int

    Und mit runden Klammern kann man wie in der Mathematik die Lesereihenfolge ändern.

    int (*a)[5];//a ist ein Zeiger auf ein Array mit 5 ints

    int a[5][6];//a ist ein Array von 5 Arrays von 6 ints

    int *a[5][6];//a ist ein Array von 5 Arrays von 6 Zeigern auf int

    int (*a)[5][6];//a ist ein Zeiger auf ein Array von 5 Arrays von 6 ints

    int (*a[5])[6];//a ist ein Array von 5 Zeigern auf Arrays mit 6 ints

    int (*a[5][6]);//a ist ein Array von 5 Arrays von 6 Zeigern auf int

    int *(*a[5])[6];//a ist ein Array von 5 Zeigern auf Arrays von 6 Zeigern auf int

    int *(*a[5][6]);//a ist ein Array von 5 Arrays von 6 Zeigern auf Zeiger auf int

    Und der Trick wird bei Funktionen erst so richtig unterhaltsam.

    (Zur Erinnerung: rechts vor links lesen.)
    int a(double);//a ist eine Funktion, die nimmt double und gibt zurück einen int

    int (*a)(double);//a ist eine Zeiger auf eine Funktion, die nimmt double und gibt zurück einen int

    int a(double)[5];//a ist eine Funktion, die nimmt double und gibt zurück ein Array von 5 int//geht übrigens nicht, wie Arcot schrieb, Funktionen können keine Array zurückgeben

    int (a(double))[5];//a ist eine Funktion, die nimmt double und gibt zurück ein Array mit 5 int

    int *a(double)[5];//a ist eine Funktion, die nimmt double und gibt zurück ein Array mit 5 Zeigern auf int

    int (*a)(double)[5];//a ist ein Zeiger auf eine Funktion, die nimmt double und gibt zurück ein Array mit 5 Zeigern auf int

    int (*a(double))[5];//a ist eine Funktion, die nimmt double und gibt zurück einen Zeiger auf ein Array mit 5 ints

    char (*getfile())[260];//getfile ist eine Funktion, die nimmt void und gibt zurück einen Zeiger auf ein Array mit 260 chars

    char (&getfile())[30][260];//getfile ist eine Funktion, die nimmt void und gibt zurück eine Referenz auf ein Array mit 30 Arrays mit 260 chars



  • 😮 WOOOW bin noch am lesen aber wollte schon jetzt schreiben VIELEN HERZLICHEN DANK!! Für die Arbeit!



  • 😃 Ich habs mir ausgedruckt !


  • Mod

    Gargamelt schrieb:

    😃 Ich habs mir ausgedruckt !

    Das brauchst du dir nicht auszudrucken. Drucke dir entweder die Regeln aus, oder gehe einfach auf cdecl.org, wo du bequem jede Deklaration "übersetzen" kannst.

    @volkard: Die Regel kannte ich gar nicht, die ist ja sehr nett.


Anmelden zum Antworten