Konstante Memberfunktion erzwingen?
-
Hi
Gibt es eine Möglichkeit zu erzwingen, dass der Compiler bei einer überladenen Memberfunktion die konstante Variante verwendet außer über eine konstante Referenz/konstanten Pointer?
Also:
class foo { public: char* bar(); const char *bar() const; }; //... foo f; const char* p1 = f.bar(); //bar() const foo& rf = f; const char* p2 = rf.bar(); //bar() const const foo* pf = &f; const char* p3 = pf->bar(); //bar() const
mfg
rean
-
rean schrieb:
Hi
Gibt es eine Möglichkeit zu erzwingen, dass der Compiler bei einer überladenen Memberfunktion die konstante Variante verwendet außer über eine konstante Referenz/konstanten Pointer?
Nein. Wozu sollte das gut sein? Es gibt wenige bis garkeine vernünftigen Gründe, sowas zu machen.
-
Ich habe eine Klasse gegeben die beim Aufruf der nicht-konstanten Variante eine tiefe Kopie eines Speicherbereichs macht die ich dann auch wieder selbst aufräumen müsste. Die konstante Variante gibt einen const char* auf den internen Speicher zurück. Da mir ein const char * reicht und ich eine tiefe Kopie und das damit verbundene Aufräumen vermeiden will will ich eben sicher gehen, dass die konstante Variante aufgerufen wird.
-
Du kannst natürlich
static_cast<foo const &>(f).bar();
schreiben, aber grundsätzlich würde ich das Design deiner Klasse nochmal überdenken - ein Benutzer wird im Zweifel erwarten, dass sich beide Varianten nahezu gleich verhalten. Insbesondere wäre er überrascht (sofern er es denn wahrnimmt), dass er im einen Fall noch aufräumen muss und im anderen nicht. Ich weiß nicht, ob Templates in deinem Anwendungsfall eine Rolle spielen, aber beim Schreiben von Templates kann einen so was böse auf dem falschen Fuß erwischen.
Wahrscheinlich würde ich die non-const-Variante einfach weglassen und dem Benutzer ggf. selbst das Erstellen einer Kopie überlassen oder die non-const-Variante eindeutig umbenennen, etwa bar() const und bar_copy().
-
Wenn du sicher gehen willst, dass eine bestimmte Methode aufgerufen wird, dann wäre ein eigener Name IMO die richtige Lösung.
-
Wenn ich Einfluss auf die Klasse nehmen könnte würde ich auch einen eigenen Namen vergeben
Es handelt sich dabei übrigens um QImage::bits
http://doc.qt.nokia.com/latest/qimage.html#bitsNote that QImage uses implicit data sharing. This function performs a deep copy of the shared pixel data, thus ensuring that this QImage is the only one using the current return value.
http://doc.qt.nokia.com/latest/qimage.html#bits-2
Note that QImage uses implicit data sharing, but this function does not perform a deep copy of the shared pixel data, because the returned data is const.
[EDIT]
Ok, meine Infos waren wohl falsch. Bei der nicht-konstanten Variante wird lediglich sichergestellt, dass die Daten nicht mit einem anderen Objekt geteilt werden.
Also wird im schlimmsten Fall einmal eine Kopie erstellt.
-
Dann arbeite doch mit einer Referenz dabei wird nichts kopiert.
foo f; const char* const &p1 = f.bar(); //bar() const
-
seldon schrieb:
static_cast<foo const &>(f).bar();
Eigentlich wäre hier ein
const_cast<const foo&>(f).bar();
besser geeignet.Diesen Fakt über das QImage kann ich für zukünftiges Qt-Bashing gut verwenden, vielen Dank für die Info
-
rean schrieb:
Es handelt sich dabei übrigens um QImage::bits
Dann nimm QImage::constBits()
-
baschi schrieb:
seldon schrieb:
static_cast<foo const &>(f).bar();
Eigentlich wäre hier ein
const_cast<const foo&>(f).bar();
besser geeignet.Diesen Fakt über das QImage kann ich für zukünftiges Qt-Bashing gut verwenden, vielen Dank für die Info
Siehe mein Edit.
Qt ftw[EDIT]
Shade Of Mine schrieb:
rean schrieb:
Es handelt sich dabei übrigens um QImage::bits
Dann nimm QImage::constBits()
Leider wurde das erst mit 4.7 eingeführt, das Projekt verwendet noch 4.6.