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?
Warum sind die Operatoren mit friend deklariert? Schließlich ist int kein Friend deiner Klasse.
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 =/
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?
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.
Marcel schrieb: > Jetzt will ich es auf einem > Mikrocontroller portionieren, wobei das Problem auftritt. Und das Problem wäre? Andreas
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;".
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.