Der Kopierkonstruktor in C++
Ein Kopierkonstruktor ist ein Verfahren, das ein Objekt unter Verwendung eines anderen Objekts desselben Typs initialisieren kann.
Jede Klasse kann einen Kopierkonstruktor enthalten, der dann zum Initialisierung von Objekten jener Klasse herangezogen werden kann.
Wir haben den Kopierkonstruktor der Klasse »::std::string« schon im Grundkurs verwendet, aber ohne ihn zu erwähnen.
Wir zeigen ein Programm, in dem ein Kopierkonstruktor zum Einsatz kommt.
main.cpp
#include <initializer_list>
#include <ostream>
#include <iostream>using namespace ::std::literals;
int main()
{ auto s { "echo"s };
::std::cout << s << '\n'; }transcript
echo
Bei der Initialisierung des Objekts »s« wird die Zeichenfolge »echo« von dem temporären Objekt »"echo"s« in das Objekt »s« kopiert. Zur Ausführung dieses Kopiervorgangs wird der Kopierkonstruktor der Klasse von »s« verwendet, also der Kopierkonstruktor der Klasse »::std::string«.
Der Kopierkonstruktor einer Klasse hat also keinen Namen, unter dem er wie eine Funktion aufgerufen werden, sondern er wird in bestimmten Fällen herangezogen.
Die Proklamation eines Konstruktors in einer Klassenproklamation ähnelt der Proklamation einer Funktion, nur fehlt der Rückgabetyp, und an Stelle eines Funktionsname steht der Name der Klasse.
- Proklamation der Klasse »::std::string« (vereinfacht)
namespace std
{ class string
{ string( string const str );
char const * c_str() const;
char const * data() const; }}
Die Proklamation »string( string const str )« bedeutet also, daß es in der Klasse »::std::string« einen Konstruktor gibt, der ein Objekt der Klasse »::std::string« initialisieren kann, und der dazu ein anderes Objekte, welches durch den Parameter repräsentiert wird und ebenfalls die Klasse »::std::string« als Typ hat, heranziehen kann.
Die Definition »auto s { "echo"s };« des weiter oben stehenden Programmbeispiels ist kein Aufruf des Konstruktors, sondern eine Variablendefinition mit Initialisierung. Der Konstruktur wird dabei herangezogen, um das Objekt »s« auf der Grundlage des Objekts »"echo"s« zu initialisieren, weil dies durch C++ für solche Variablendefinitionen mit Initialisierung so festgelegt ist: Initialisierungen eines Objekts mit einem anderen Objekt derselben Klasse verwenden den Kopierkonstruktor der Klasse jenes Objektes.
Es gibt auch Klassen ohne Kopierkonstruktor. Man kann dann keine Initialisierung von Objekten solcher Klassen durchführen, bei denen ein Objekt jener Klasse kopiert wird. Beispielsweise hat die Klasse von »::std::cout« keine Kopierkonstruktor. Man kann dann kein Objekte jener Klasse kopieren.
main.cpp
#include <initializer_list>
#include <ostream>
#include <iostream>using namespace ::std::literals;
int main()
{ auto o { ::std::cout };
o << "echo"s << '\n'; }transcript (vereinfacht)
Fehler: Der Typ von "o" hat keinen Kopierkonstruktor.