Richtiges Benutzen vom überladenen Operator()



  • Hallo,

    Das einarbeiten in die C++-Praktiken erweist sich für mich an einigen Stellen doch etwas beschwerlich. Deswegen habe ich mal eine Frage. Ich habe eine Klasse Matrix. In dieser habe ich diverse Operatoren überladen. Zum Besipiel den () Operator zur Indezierung. Das funktioniert ganz gut, nur bei einer bestimmten Sache halt nicht. Ich vermute, dass es mit an meiner mangelnden Kenntniss liegt. Leider finde ich dazu auch nichts im Netz oder in der Literatur (und da habe ich viele). Vielleicht verstehe ich es auch nur nicht oder es mangelt mir an Abstraktionsvermögen, egal. Folgendes Problem:

    Matrix<double> mat1(10,10,0.0) // Hier wird die Matrix initilisiert mittels dem Konstruktor rows=10 und cols =10 und Initialwert=0.0

    Matrix<double>* mat2 = new Matrix<double>(10,10,0.0) // Auch hier wird die Matrix initilisiert mittels dem Konstruktor rows=10 und cols =10 und Initialwert=0.0

    Jetzt will ich mittels einem überladenen Operator () auf die Elemente zugreifen.

    mat1(0,0)=10; // Hier wird nun in das Element Zeile 0 und Spalte 0 die Zahl 10 reingeschrieben --> Das funktioniert perfekt

    wenn ich jetzt folgendes mache, funtkioniert es nicht.

    mat2(0,0)=10;

    Ok, denke ich, mat2 ist ja auch ein Zeiger vom Typ Matrix<double>, also habe ich probiert:

    *mat2(0,0)=10;

    Geht aber nicht. Was mache ich falsch und warum?

    Ich bitte den Programmier-Koryphäen unter euch gnädig zu sein und mich nicht zu verpflücken.

    Grüße
    Sven



  • (*mat2)(0, 0) = 10;


  • Mod

    Der Dereferenzierungs-Operator bindet schwächer als der operator() , daher muss die Dereferenzierung in Klammern gesetzt werden.

    Die Stärke der Operatorbindung kannst du für jeden Operator hier einsehen: http://en.cppreference.com/w/cpp/language/operator_precedence

    Im Prinzip ist das aber alles aus der Sprachlogik deduzierbar.



  • Wow, hat funktioniert und ging ja erschreckend einfach. Danke für die Antworten und den Link zur Erklärung dazu. Jetzt kann ich mich weiter durchforsten.

    Nochmals vielen Dank.



  • Ich habe nun in einer Klasse eine eigene Matrix-Variable deklariert und zwar als pointer

    class A{

    public:
    Matrix<double>* Test;

    In der Matrix-Klasse ist der () Operator zur Indezierung überladen.

    Im Konstruktor der Klasse A funktioniert zum Beispiel folgende Anweisung:

    Test = new Matrix<double>(3,1);
    (*Test)(0,0) = 16;
    (*Test)(1,0) = 17;
    (*Test)(3,0) = 18;
    *
    *
    *

    So, nun will ich aber in der Main auf die Variable zureifen können, daher ist diese auch als public deklariert.
    A* A_1 = new A;

    Nun will ich auf die Variable Test zugreifen, bzw. verändern mit:

    A_1->Test(0)=12; //Funktioniert nicht
    (A_1->Test)(0)=12; //Funktioniert nicht
    (*A_1).Test(0,0)=12; //Funktioniert nicht
    ((*A_1).Test)(0,0)=12; //Funktioniert nicht

    Mir ist ja auch etwas peinlich, aber ich stehe etwas auf dem Schlauch. Ich hoffe ihr könnt helfen.

    P.S. Auf die hinterlegten Methoden der Matrixvariable kann ich ohne Probleme zugreifen, nur nicht auf die Varibalen bzw. auf die Operatorüberladung (). Und ich möchte keine Setter-Methode schreiben, da ich den direkten Zugriff präfferiere.



  • (*A_1->Test)(0,0) = 12;

    Aber warum benutzt du überall Zeiger?



  • Das gibts doch nicht, gestern Abend alles mögliche versucht, aber das offensichtliche nicht. Naja, betriebsblind halt. Aber danke für die schnelle und hilfreiche Antwort.

    So zu deiner Frage. In der Klasse A deklariere ich Variablen mit dem eigens kreierten Typ Matrix. Dabei sollte aber ein ganz spezieller Matrix-Konstruktor aufgerufen werden. Und da das in der Deklaration in einer Klasse (z.B. Klasse A) nicht geht, musste das im Konstruktor von der Klasse A geschehen. Dafür musste ich aber die Matrixvariablen definieren mit:

    A::A(){
    Matrix *Test=new Matrix(1,1,2); //als Beispiel --> Nun wird der Konstrukor von Matrix aufgerufen

    Mir ist klar, ich könnte auch eine Methode in der Matrix-Klasse schreiben, die das gleiche macht wie der Konstruktor der Matrix-Klasse und diese dann aufrufen, aber irgendwie empfand ich das als nicht schön bzw. unsauber. Ich bräuchte die Variablen zwar nicht als Pointer zu deklarieren, aber wie schon gesagt, fand ich das unschön den Konstruktor zu übergehen.



  • <- die Lösung.


Anmelden zum Antworten