mikrocontroller.net

Forum: PC-Programmierung Operatorüberladung in C++


Autor: Marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe eine Klasse geschrieben, die einen Datensatz verwalten soll. 
Für die Klasse habe ich die wichtigsten Operatoren überladen.

Deklariert habe ich das ganze so:

template <class T>
class DataClass
{
...

template <class F>
friend DataClass<T> operator+( F, DataClass<T> );

...
}

Implementiert anschließend:

template <class F, class T>
DataClass<T> operator+( F faktor, DataClass<T>& data  )
{
  T *field;
  field = (T*) mem_malloc( data.getElements()*sizeof(T) );

  for( int i = 0; i<data.getElements(); i++ )
  {
    field[i] = faktor + data.field[i];
  }
  DataClass<T> dat;
  dat.setData( field );
  dat.setElements( data.getElements() );
  return dat;
}

Ich kann nun auch wunderbar "a = a + 1;" schreiben, jedoch nicht "a = 1 
+ a;".

Ich hatte das ganze zuerst unter VisualC++ geschrieben und getestet 
gehabt. Dort lieft mein Progremm. Jetzt will ich es auf einem 
Mikrocontroller portionieren, wobei das Problem auftritt.

Laut http://www.cpp-tutor.de/cpp/le12/ueberladen.html soll das ganze 
eigentlich gehen.

Weiß da wer weiter?

Autor: Nico22 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum sind die Operatoren mit friend deklariert? Schließlich ist int 
kein Friend deiner Klasse.

Autor: Marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Damit ich innerhalb der Funktion auf alle Elemente der Dataklasse 
zugreifen kann.

Da ich sowieso den []-Operator überladen habe, hab ich das data.field[i] 
zu data[i] geändert, wodurch die friend-Deklaration nichtmehr notwendig 
ist. Nachdem ich sie entfernte, funktioniert es wie gewollt.

Erstmal danke! Verstehen tue ich das Problem allerdings nicht =/

Autor: Ein echter Programmierer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum tut sich jemand diesen unübersichtlichen, unverständlichen und 
inhärent fehlerträchtigen und wartungsfeindlichen C-Unfug an, statt eine 
RICHTIGE Programmiersprache zu verwenden?

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist C++, kein C.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine Data Klasse ist nicht sehr schön aufgebaut.

Ist es wirklich notwendig, dass ...

  T *field;
  field = (T*) mem_malloc( data.getElements()*sizeof(T) );

  ...

  dat.setData( field );
  dat.setElements( data.getElements() );


... sich der Verwender der Klasse um die Speicherallokierung kümmert? 
Das sollte nicht sein und läuft eigentlich ein bischen dem 
objektorientierten Gedankengang zuwider:

  Objekte kümmern sich selbst um ihre internen Belange.


template <class F, class T>
DataClass<T> operator+( const F offset, const DataClass<T>& data  )
{
  DataClass<T> result( data.getCount() );

  for( size_t i = 0; i < data.getCount(); ++i )
    result[i] = data[i] + offset;

  return result;
}

So würde ich das machen.
Beachte auch das const in der Argumentliste und die Namen der 
Funktionen, die m.E. den Zweck der Funktion besser wiederspiegeln. Mit 
einer Funktion getElements verbinden wohl die meisten eine Funktion, die 
einem Zugriff auf die tatsächlichen Elemente gibt und nicht eine 
Funktion die die Anzahl der Elemente liefert. So etwas hat normalerweise 
ein 'Count' im Funktionsnamen oder ein 'Size', wenn die Funktion nicht 
slebst der Einfachheit halber 'count()' oder 'size()' heißt.

Wenn es einen guten Grund gibt, warum es keinen Konstruktor geben soll, 
der die Anzahl der zu allokierenden Elemente übernimmt, dann verpass ich 
der DataCalss noch eine allocate() Funktion. Aber den Speicher soll sich 
die DataClass Klasse selber allokieren und nicht jemand ausserhalb. Wie 
willst du sicherstellen, dass derjenige das in einer Form tut, so dass 
du im Destruktor weißt, wie du den Speicher freizugeben hast, bzw. im 
Copy Construktor eine Kopie zu erstellen hast?

Trag keine Implementierungsdetails aus einer Klasse heraus, wenn du 
nicht musst! Wie Speicher allokiert wird, ist ein 
Implementierungsdetail. Und ich hoffe, du hast einen extrem guten Grund, 
warum du mem_malloc benutzt und nicht new.

Apropos Copy Constructor.
Da dat sowieso konstruiert werden muss, kann es sich auch gleich als 
Kopie von data erzeugen
template <class F, class T>
DataClass<T> operator+( const F offset, const DataClass<T>& data  )
{
  DataClass<T> result( data );

  for( size_t i = 0; i < result.getCount(); ++i )
    result[i] += offset;

  return result;
}

Da deine Klasse sowieso offenbar einen Copy Constructor braucht, wäre 
das noch naheliegender und kann dann auch gleich noch Gebrauch von einem 
+= Operator machen.

Autor: Andreas Ferber (aferber)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marcel schrieb:
> Jetzt will ich es auf einem
> Mikrocontroller portionieren, wobei das Problem auftritt.

Und das Problem wäre?

Andreas

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Ferber schrieb:
>> Jetzt will ich es auf einem
>> Mikrocontroller portionieren, wobei das Problem auftritt.
>
> Und das Problem wäre?

Marcel schrieb:
> Ich kann nun auch wunderbar "a = a + 1;" schreiben, jedoch nicht "a = 1
> + a;".

Autor: Andreas Ferber (aferber)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus schrieb:
> Marcel schrieb:
>> Ich kann nun auch wunderbar "a = a + 1;" schreiben, jedoch nicht "a = 1
>> + a;".

Schön. Offenbar kann er es aber doch schreiben, im Posting klappt es ja.
Also muss das Problem irgendwo anders drin bestehen, z.B. in einer 
Compiler-/Linkerfehlermeldung (mein Tip: Linker)...

Andreas

Autor: Marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe mein Programm entsprechend den Anregungen von  Karl heinz Buchegger 
geändert. Danke schonmal für die Tipps.
Die mem_alloc-Methode benutze ich, da es nach ca. 400Bytem die ich 
reserviert habem zu einem Überlauf/Überschreiben des Programmcounters 
o.ä. kommt, wodurch der Controlller macht, was er will. Wie ich die 
Größe des Heaps ändern könnte, oder ob die mem_alloc-Funktion da mit 
reinspielt, die ein anderer, feststehender Programmteil vorraussetzt, 
konnte ich noch nicht verifizieren.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marcel schrieb:
> Habe mein Programm entsprechend den Anregungen von  Karl heinz Buchegger
> geändert. Danke schonmal für die Tipps.
> Die mem_alloc-Methode benutze ich, da es nach ca. 400Bytem die ich
> reserviert habem zu einem Überlauf/Überschreiben des Programmcounters
> o.ä. kommt, wodurch der Controlller macht, was er will.

Bitte schreibe Controllerfragen in Zukunft ins GCC Forum (auch wenn du 
einen anderen Compiler benutzt). Du bist hier im PC-Programmierung 
Forum. Da gibt es derartige Probleme normalerweise nicht und ich gehe 
davon aus, dass Speicherallokierung nicht an irgendwelche großartigen 
technologischen Limits gebunden ist.
Danke.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.