Funktion überladen, jenachdem ob object const ist oder nicht.



  • Hallo,
    ich habe zwei Objekte der Klasse A:

    A * a1
    const A * a2
    

    Wie kann ich dafür sorgen, dass der Pointer auf Int im Fall a1 normal, und im Falle a2 const ist? Kann ich das entsprechend überladen, oder muss ich die Funktion zweimal implementieren, einmal als const und einmal als nicht const?

    class A{
    public:
    int * m getM(); // call this, if A is an object.
    const int * m getM() const; // call this if A is a const object.
    private:
    _m
    }
    


  • elfstone schrieb:

    Kann ich das entsprechend überladen, oder muss ich die Funktion zweimal implementieren, einmal als const und einmal als nicht const?

    Wäre doch beides dasselbe, oder?

    ...egal, so oder so ja.



  • Ja, wäre beide male die selbe Funktion, daher will ich sie nicht zweimal schreiben (code duplication).



  • elfstone_von_oben schrieb:

    Ja, wäre beide male die selbe Funktion, daher will ich sie nicht zweimal schreiben (code duplication).

    bei überladung musst du sie aber auch 2 mal schreiben.

    das problem ist halt, du willst ähnliche funktionen, aber nicht gleiche... dh du musst sie 2 mal implementieren.



  • elfstone_von_oben schrieb:

    Ja, wäre beide male die selbe Funktion, daher will ich sie nicht zweimal schreiben (code duplication).

    Ich meinte eher, dass du mit Überladen auch zweimal eine Funktion schreiben musst (bzw. dass es sich gerade um eine Überladung handelt). 😉

    Wenn von einem einzeiligen Getter die Rede ist, also

    return myM;
    

    dann dupliziere den Code. Du erzeugst nur noch viel mehr Code, wenn du das zu vereinheitlichen versuchst.



  • daher will ich sie nicht zweimal schreiben

    Musst Du aber. Wenn eine davon komplexer ist und/oder Du die Implementierung nicht "verraten" willst, könnte man es soch machen:

    class Foo
    {
    public:
      const int * m getM() const; // "aufwaendige" Implementierung
                                  // in cpp-Datei versteckt.
    
      int * m getM() {
        A const* me = this;
        return const_cast<int*>(me->getM());
      }
    
      [...]
    }
    

    Ist nicht ganz so schön, aber machbar/legal. Ich habe so etwas schonmal bei einer eigenen Datenstruktur gemacht. Eine bestimmte Funktion sollte ein Element suchen und einen Iterator darauf zurück geben. Für die Rückgabe auf einen einfachen Datenmember ist das aber Overkill.



  • Oder:

    class MyClass
    {
    public:
    	int* GetMember()
    	{
    		return GetMemberImpl();
    	}
    
    	const int* GetMember() const
    	{
    		return GetMemberImpl();
    	}
    
    private:
    	int* GetImpl() const
    	{
    		// Aufwand!
    	}
    };
    

    Falls der int* aber auf einen Member der Klasse zeigt, ist const_cast wieder notwendig.

    Man sollte übrigens vorsichtig sein mit const_cast : Das ist nämlich nur solange okay, wie das Originalobjekt (nicht Zeiger oder Referenzen darauf) nicht als konstant deklariert ist. Hier lässt sich das leicht erkennen, indem man sich überlegt, ob der nicht-konstante Getter seine Aufgaben ebensogut ohne const_cast erledigen könnte.



  • int * m getM();
    

    Was hat eigentlich das m dort zu suchen?


Anmelden zum Antworten