C++ Kopierkonstruktor / Referenzparameter

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
PietCN
Beiträge: 13
Registriert: Sa Jan 16, 2016 10:49 pm

C++ Kopierkonstruktor / Referenzparameter

Beitrag von PietCN » Sa Jan 16, 2016 11:09 pm

Hallo liebe Leute,
als erstes kurz über mich.

Ich bin dabei privat als Hobby C / C++ zu lernen bzw. lerne noch dazu momentan C in einer Techniker Schule. Da wird aber das Wissen auf die Mikrokontroller-Technik reduziert.
Da mich das ganze Thema aber weit aus mehr interessiert bin ich dem eigentlichem Lernstoff schon wesentlich voraus.

Nun zur Frage: (C++)

Ich habe ein Verständnisproblem. Es funktioniert, aber ich weiß nicht warum.
Es geht um einen Kopierkonstruktor einer Klasse, und zwar ist dieser mit einem, meiner Meinung nach, Referenzparameter ausgestattet.

Nur um mein Wissen darüber zu bestätigen: Ein Referenzparameter ist an sich ein Zeiger, ergo beinhaltet er als Inhalt eine Adresse, aber es ist für den Compiler eigentlich nur der Inhalt auf dem der Zeiger zeigt interessant.

Code: Alles auswählen

CMessreihe::CMessreihe(CMessreihe& Quelle)
{
  Anzahl = Quelle.Anzahl;

  if (!(pMesswert = new float[Anzahl]))
  {
    cout << RAM_ERROR << endl;
    _getch();
    exit(1);
  }
  *pMesswert = *Quelle.pMesswert;
}
Das ist der entsprechende Code zum Kopierkonstruktor. Ich hoffe bis dahin hab ich richtig aufgepasst. Kurz zum Programm:

Es sollen simulierte Messwerte in einem allokierten Speicher, dessen Anzahl / Größe vom Benutzer her angegeben werden soll, gespeichert werden. Das ganze soll dann in einem zweiten Objekt kopiert werden.

Das Verständnisproblem was ich nun habe ist: Warum müssen die Sternchen (*) in der vorletzten Zeile sein ?

Code: Alles auswählen

*pMesswert = *Quelle.pMesswert;
Ich war eigentlich der Meinung dank des Referenzparameter, insofern er wirklich einer ist, dies nicht mehr erforderlich sei?
Ohne die Sternchen(*) [oder Zugriffsoperatoren] kommen nach dem Destruktor des Kopierten Objektes und vor dem Destruktor des eigentlichen Objektes zu sehr verwirrenden Fehlermeldungen.

Destruktor :

Code: Alles auswählen

CMessreihe::~CMessreihe()
{
 
  delete[] pMesswert;
}
So, ich hoffe das ihr mir Erleuchtung bringen könnt. :)

Mit freundlichen Grüßen


Falls es noch erforderlich ist, das wäre die eigentliche Deklaration der Klasse :

Code: Alles auswählen

class CMessreihe {
protected:
  float *pMesswert;
  int Anzahl;
public:
  CMessreihe(CMessreihe& K_Messreihe);
  CMessreihe(int Anzahl);
  ~CMessreihe();
  void SetWert(int i, float Wert);
  float GetWert(int i);
  void Mittelwert();
  void MinWert();
  void MaxWert();
};

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: C++ Kopierkonstruktor / Referenzparameter

Beitrag von nufan » So Jan 17, 2016 4:48 am

Hallo :)
PietCN hat geschrieben:Nur um mein Wissen darüber zu bestätigen: Ein Referenzparameter ist an sich ein Zeiger, ergo beinhaltet er als Inhalt eine Adresse, aber es ist für den Compiler eigentlich nur der Inhalt auf dem der Zeiger zeigt interessant.
Ja.
PietCN hat geschrieben:Das Verständnisproblem was ich nun habe ist: Warum müssen die Sternchen (*) in der vorletzten Zeile sein ?

Code: Alles auswählen

*pMesswert = *Quelle.pMesswert;
Ich war eigentlich der Meinung dank des Referenzparameter, insofern er wirklich einer ist, dies nicht mehr erforderlich sei?
Du hast eine Referenz auf dein übergebenes Objekt "Quelle", deswegen musst du es nicht mehr dereferenzieren. In dieser Zeile beziehen sich die * aber auf dein Member "pMesswert", was ein float-Zeiger ist. Schau dir dazu die Prioritäten der Operatoren an (https://www.proggen.org/doku.php?id=c:expr:opprio): Der '.' steht über dem '*'. Das heißt es wird zuerst auf "pMesswert" zugegriffen und dann erst dereferenziert.

Allerdings würde ich diese Zeile semantisch in Frage stellen. Was willst du damit erreichen? Du kopierst hier nur den ersten Wert des "Quelle.pMesswert"-Arrays auf den ersten Wert von deinem lokalen "pMesswert". Willst du Arrays als ganzes kopieren brauchst du dafür eine Schleife bzw. etwas wie memcpy().

PietCN
Beiträge: 13
Registriert: Sa Jan 16, 2016 10:49 pm

Re: C++ Kopierkonstruktor / Referenzparameter

Beitrag von PietCN » So Jan 17, 2016 9:47 am

Ah, das klingt irgendwie logiscn. Wenn ich mir das ein paar mal durch den Kopf gehen lassen, verstehe ich das auch. :D

Zu deiner Anmerkung : Ich hab gelernt das der Name des Arrays, in dem Fall pMesswert, da dieser der Zeiger auf das erste Element ist des allokierten Speichers, gleich die Adresse des Arrays ist. Und über eine Schleifengesteuert Ausgabe jedes einzelnen Elements via:

Code: Alles auswählen

for (int i; i < Anzahl; i++)
  cout << pMesswert[i] << endl;
sind alle Werte auch richtig kopiert worden. Also dahergehend würde ich behaupten das dies so richtig sei. :)

Ich weiß nicht warum, aber die ganze Zeigertechnik mit Arrays zusammen viel mir von Anfang an relativ leicht. :D

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: C++ Kopierkonstruktor / Referenzparameter

Beitrag von nufan » So Jan 17, 2016 9:43 pm

PietCN hat geschrieben:Zu deiner Anmerkung : Ich hab gelernt das der Name des Arrays, in dem Fall pMesswert, da dieser der Zeiger auf das erste Element ist des allokierten Speichers, gleich die Adresse des Arrays ist.
Das stimmt so, lass dir mit diesem Gedanken mal die genannte Zeile durch den Kopf gehen. Du dereferenzierst jeweils das erste Element und weist es zu.
PietCN hat geschrieben:Und über eine Schleifengesteuert Ausgabe jedes einzelnen Elements via:

Code: Alles auswählen

for (int i; i < Anzahl; i++)
  cout << pMesswert[i] << endl;
sind alle Werte auch richtig kopiert worden. Also dahergehend würde ich behaupten das dies so richtig sei. :)
Zeig mal bitte vollständigen und kompilierbaren Code, wo du das so hast.

PietCN
Beiträge: 13
Registriert: Sa Jan 16, 2016 10:49 pm

Re: C++ Kopierkonstruktor / Referenzparameter

Beitrag von PietCN » Fr Jan 22, 2016 9:53 pm

Okay, ich hab mir meinen Code nochmal genauer angeschaut und alles durchkompilieren lassen und muss leider zugestehen das es so doch nicht funktioniert. Meine Annahme basierte noch auf ein Programm, welches ich davor geschrieben hatte, da handelte es sich aber nur um ein Char, nicht um ein ganzes Array.

Also sehe ich das richtig das ich die Array-Elemente alle in einer Schleife im Kopierkostruktor durchgehen muss um diese dann einzeln zu übergeben bzw. zu kopieren?

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: C++ Kopierkonstruktor / Referenzparameter

Beitrag von nufan » Fr Jan 22, 2016 10:33 pm

PietCN hat geschrieben:Also sehe ich das richtig das ich die Array-Elemente alle in einer Schleife im Kopierkostruktor durchgehen muss um diese dann einzeln zu übergeben bzw. zu kopieren?
Entweder einzeln in einer Schleife kopieren oder beide Arrays (als ganzes) an die Funktion übergeben.

Antworten