const / non-const Konstruktur - ist das möglich?



  • Hallo,

    bin momentan dabei, mal wieder etwas an einer String Klasse zu basteln.
    Bisher ist es so, dass immer eine Kopie der Quelle beim Konstruieren gemacht wird. Nun möchte ich dieses Verhalten für String-Literale spezialisieren. Wozu Speicher anfordern und eine Kopie erstellen, wenn das Literal sowieso während der gesamten Laufzeit gültig ist?
    Es wäre deshalb schön, wenn Folgendes funktionieren würde:

    string = "Hallo"; // Kopie erstellen, mit Speicherreservierung und allem was dazu gehört
    const string = "Hallo"; // keine Kopie erstellen, das Literal lediglich "referenzieren"
    

    Nun ist C++ ja leider kein Wunschkonzert, dh sowas wie einen "const Konstruktur" gibt es nicht.
    Gibt es trotzdem eine Möglichkeit, sowas zu realisieren?

    Oder bleibt mir letztendlich nichts anderes übrig, als zwei Klassen zu verwenden? Nach dem Motto:

    string = "Hallo";
    const_string = "Hallo";
    

    Wobei dann string wiederum einen ctor für const_string hat.

    Und bitte keine Vorschläge ala "mach eine copy-on-write Klasse", da die String Klasse darauf ausgelegt ist, vergleichbar mit nativen Zeichenarrays keinen Overhead zu haben.



  • Naja, Du wirst wohl zwei Klassen brauchen. Jedenfalls sehe ich keine andere Möglichkeit. Ganz einfach deshalb, weil man einem const char* nicht ansehen kann, ob er auf ein Literal zeigt oder nicht. Das ist Wissen, was nur Du haben kannst und dem Compiler explizit verraten musst.

    Solange alles in einer Übersetzungseinheit bleibt, ist das ja kein Problem, Literale zu erkennen am "Hingucken". Sobald es aber auf mehrere Object-Files geht, fehlt schlichtweg das Wissen, ob der const char*, der irgendwo her kommt, denn auf ein Literal zeigt oder nicht.



  • du musst ausnutzen, das ein stringliteral kein const char* sondern ein const char[] ist ;).

    nun ist natürlich klar, dass es kein const_ctor gibt, aber du kannst ja ne bool variable anlegen die speichert woraus der string konstruiert wurde, und wenn der user dann irgendwas am string verändern will, umkonstruieren.



  • Der Geschwindigkeitsgewinn durch das Unterbinden des Kopierens beim Konstruktoraufruf ist nicht wirklich ein Performance-Problem, weil 99% der Strings sowieso erst später erzeugt bzw. eingelesen werden.

    Deshalb macht es wenig Sinn dies zu optimieren.



  • otze schrieb:

    du musst ausnutzen, das ein stringliteral kein const char* sondern ein const char[] ist ;).

    Möchte man meinen. Scheint allerdings nicht jeden Compiler zu interessieren.

    #include <iostream>
    using namespace std;
    
    class foo
    {
    public:
    	template <size_t N>
    	foo(const char (&)[N])
    	{
    		cout << "Literal" << endl;
    	}
    	foo(const char*)
    	{
    		cout << "kein Literal" << endl;
    	}
    };
    
    int main()
    {
    	foo("hallo");
    	return 0;
    }
    

    Hier wird zB der 'const char*' ctor aufgerufen (GCC + MSC). Allerdings ist das Problem, ein Literal zu erkennen, nicht das eigentliche Problem, da es dafür bereits eine Lösung gibt.

    otze schrieb:

    nun ist natürlich klar, dass es kein const_ctor gibt, aber du kannst ja ne bool variable anlegen die speichert woraus der string konstruiert wurde, und wenn der user dann irgendwas am string verändern will, umkonstruieren.

    Ja, daran hab ich auch schon gedacht. Leider hilft mir das nicht wirklich weiter, da ich immer noch nicht weiss, ob ein const oder non-const Objekt erzeugt wurde. Die STL scheint da zB ähnliche Probleme zu haben, deshalb gibt es zB iterator und const_iterator.

    Mathias schrieb:

    Der Geschwindigkeitsgewinn durch das Unterbinden des Kopierens beim Konstruktoraufruf ist nicht wirklich ein Performance-Problem, weil 99% der Strings sowieso erst später erzeugt bzw. eingelesen werden.

    Schon klar, dass man damit keine grossen Performancesprünge macht. Darum geht es aber auch nicht. Die String Klasse ist mehr oder weniger ein Hobby Projekt, an dem ich von Zeit zu Zeit mal etwas rumbastel, nur damit sie einem etwas besser gefällt. 😉

    Nun, zur Not könnte ich natürlich mit einer zweiten Klasse leben, auch wenn's nicht so schön ist, wie eine generelle String Klasse zu haben. Wer trotzdem noch irgendwelche Ideen hat, nur her damit.


Anmelden zum Antworten