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


von Marcel (Gast)


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?

von Nico22 (Gast)


Lesenswert?

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

von Marcel (Gast)


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 =/

von Ein echter Programmierer (Gast)


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?

von Simon K. (simon) Benutzerseite


Lesenswert?

Das ist C++, kein C.

von Karl H. (kbuchegg)


Lesenswert?

Deine Data Klasse ist nicht sehr schön aufgebaut.

Ist es wirklich notwendig, dass ...
1
  T *field;
2
  field = (T*) mem_malloc( data.getElements()*sizeof(T) );
3
4
  ...
5
6
  dat.setData( field );
7
  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.


1
template <class F, class T>
2
DataClass<T> operator+( const F offset, const DataClass<T>& data  )
3
{
4
  DataClass<T> result( data.getCount() );
5
6
  for( size_t i = 0; i < data.getCount(); ++i )
7
    result[i] = data[i] + offset;
8
9
  return result;
10
}

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
1
template <class F, class T>
2
DataClass<T> operator+( const F offset, const DataClass<T>& data  )
3
{
4
  DataClass<T> result( data );
5
6
  for( size_t i = 0; i < result.getCount(); ++i )
7
    result[i] += offset;
8
9
  return result;
10
}

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.

von Andreas F. (aferber)


Lesenswert?

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

Und das Problem wäre?

Andreas

von Rolf Magnus (Gast)


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;".

von Andreas F. (aferber)


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

von Marcel (Gast)


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.

von Karl H. (kbuchegg)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.