mikrocontroller.net

Forum: Compiler & IDEs Objekte in C


Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

folgendes Problemchen: In einer Liste von Objekten mit verschiedenem Typ 
soll zyklisch die Methode "runObject" aufgerufen werden.
Jaja, ich weiss, C ist nicht objektorientiert. Deshalb möchte ich 
versuchen, in C Strukturen zu schafen, mit denen eine "quasi" 
Objektorientierung entsteht.
typedef struct
{
  int seitenlaenge;  
}dreieck_t;

typedef struct
{
  int seiteA;
  int seiteB;  
}rechteck_t

....

dreieck_t d;
recheck_t r;

runObject(d);
runObject(r);  


Hat jemand von euch schon einmal so einen Ansatz verfolgt? Wie kann ma 
es besser machen?

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
chris schrieb:

> Jaja, ich weiss, C ist nicht objektorientiert.

Manche Vorurteile sterben wohl nie aus :-/

> folgendes Problemchen: In einer Liste von Objekten mit verschiedenem Typ
> soll zyklisch die Methode "runObject" aufgerufen werden.

Ich sehe in deinem Beispiel weder eine Liste, noch einen Zyklus. Mir 
wird ueberhaupt nicht klar, was du nun eigentlich wirklich machen 
moechtest.

Wenn du virtuelle Methoden haben moechtest, wirst du einen 
Funktionszeiger in deine Struktur aufnehmen muessen.

Willst du ueberladene Methoden, wirst du darauf verzichten muessen - 
aber das ist doch sowieso nur Namenskosmetik.

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
runObject muß unterscheiden können, was für ein Objekt übergeben wird.
Es funktioniert so, wenn du es wie folgt machst

typedef struct
{
  int seitenlaenge;  
}dreieck_t;

typedef struct
{
  int seiteA;
  int seiteB;  
}rechteck_t

typedef struct
{
  int objectTyp;
  void *obj;  
}object_t

....

dreieck_t d;
recheck_t r;
object_t  o;

o.objectTyp = 1;
o.obj       = &d;

runObject(o);

o.objectTyp = 2;
o.obj       = &r;
runObject(o);  


900ss

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

Bewertung
0 lesenswert
nicht lesenswert
> Deshalb möchte ich
> versuchen, in C Strukturen zu schafen, mit denen eine "quasi"
> Objektorientierung entsteht.

Dann ist wahrscheinlich deine beste Option die, dass du den Mechanismus 
von C++ virtuellen Funktionen nachbaust. Da du nur 1 virtuelle Funktion 
hast, lohnt sich eine extra VTable nicht, anstelle des VTable Pointers 
im Objekt kannst du auch gleich den Funktionszeiger nehmen
typedef void (*runFkt)( void * );

typedef struct
{
  void * obj;
  runFkt fnct;
} object_vt_t;

typedef struct
{
  int seitenlaenge;  
}dreieck_t;

typedef struct
{
  int seiteA;
  int seiteB;  
}rechteck_t

void runDreieck( void * obj )
{
  // obj muss ein Pointer auf ein Dreieck sein, sonst
  // wäre diese Funktion nie aufgerufen worden
  dreieck_t* d = ( dreieck_t *)obj;

  // mach was mit d->
  ...
}

void runRechteck( void * obj )
{
  // obj muss ein Pointer auf ein Rechteck sein, sonst
  // wäre diese Funktion nie aufgerufen worden
  rechteck_t* r = ( rechteck_t *)obj;

  // mach was mit r->
  ...
}


  ....
// in die Liste baust du jetzt 'Objekte' vom Typ object_vt_t ein.
// In jedem object_vt_t steht ein Pointer auf das 'Objekt' und ein
// Pointer auf die Funktion, die dieses Objekt bearbeitet
....
// jetzt nur mal als Beispiel

  dreieck_t drei1;
  object_vt_t obj1 = { drei1, runDreieck };

  rechteck_t recht1;
  object_vt_t obj2 = { recht1, runRechteck };

  obj1.fnct( obj1.obj );    // rufe runDreieck indirekt auf
  obj2.fnct( obj2.obj );    // rufe runRechteck indirekt auf

  ...


Alternativ könnte man auch mit diversen Typflags arbeiten, die in der 
Liste mitgespeichert werden und an eine run Funktion mitgegeben werden. 
In der Funktion gibt es dann einen grossen switch-case über diesen Typ, 
der darüber entscheidet wie es mit dem übergebenen Pointer weitergeht. 
Die Variante mit den Funktionspointern ist aber meistens besser 
erweiterbar und auch schneller.

Autor: RMP (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo KH,

warum uebergibst du der Funktion "fnct" einen Pointer auf das Object 
selbst?
Kann man es nicht bewerkstelligen, dass innerhalb des Objects das Object 
selbst bekannt ist?

Sowas wie ein "this" Zeiger in C++.

MFG

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

Bewertung
0 lesenswert
nicht lesenswert
RMP schrieb:
> Hallo KH,
>
> warum uebergibst du der Funktion "fnct" einen Pointer auf das Object
> selbst?

Damit die Funktion auch auf dem 'Objekt' selbst arbeiten kann.

> Kann man es nicht bewerkstelligen, dass innerhalb des Objects das Object
> selbst bekannt ist?

Innerhalb welchen Objektes?
Da ist kein Objekt. Da ist nur eine Funktion, die auf einer 
Datenstruktur arbeiten soll und irgendwie mitkriegen muss, welche 
konkrete Ausprägung dieser Datenstruktur es sein soll.

> Sowas wie ein "this" Zeiger in C++.

Genau so macht das auch der C++ Compiler. Nur macht er es so, dass du 
das nicht siehst :-) Aber im Geheimen wird jeder Memberfunktion ein 
zusätzlicher Paramater angehängt, den du in der Funktion mittels 'this' 
ansprechen kannst.

So etwas
class A
{
  public:
    void foo( int b )   { member = b; }

  protected:
    int member;
};

int main()
{
  A a, b;
  a.foo( 5 );
  b.foo( 7 );
}

wird vom C++-Compiler so bearbeitet
struct A
{
  int member;
};

inline void A_foo_vi( struct A* const this, int b )
{
  this->member = b;
}

int main()
{
  struct A a, b;
  A_foo_vi( &a, 5 );
  A_foo_vi( &b, 7 );
}

und in der Tat haben die ersten C++ Compiler genau so gearbeitet und C++ 
zuerst nach C 'übersetzt'. Die heutigen Compiler machen diesen Schritt 
nicht mehr explizit, aber konzeptionell ist es immer noch dasselbe.

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für eure Antworten.

Ich sehe ein, dass der Ansatz von KH im Vergleich zum Ansatz von 900ss 
eine schneller Ausführungsgeschwindigkeit bringt. Allerdings bin ich mir 
noch nicht sicher, ob die Objektunterscheidung in der runObject Function 
nicht übersichtlicherwäre, wenn sie über eine case Anweisung 
durchgeführt wird, wie von 900ss vorgeschlagen.

Nach einigem Nachdenken ist für mich ein neues Problem aufgetaucht: Wie 
wird die Allokation des Speichers für die Objekte am günstigsten 
bewerkstelligt, wenn ich die Objektliste erzeugen will?
object_vt_t ObjektListe[10];

ObjektListe[0]= { recht1, runRechteck };
ObjektListe[1]= { drei1, runDreieck };
....

Die Objektliste soll zur Laufzeit veränderbar sein.
Bei C++ ist der Vorgang ja relativ einfach. Man kann ein Objekt mit 
"new" erzeugen. Im obigen Fall scheint mir das schwierig.

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

Bewertung
0 lesenswert
nicht lesenswert
chris schrieb:

> Bei C++ ist der Vorgang ja relativ einfach. Man kann ein Objekt mit
> "new" erzeugen. Im obigen Fall scheint mir das schwierig.

malloc und Zuweisungen sind schon erfunden.

BTW: ein statisch allokiertes Array als 'Liste' zu bezeichnen, ist schon 
etwas ... verwegen.



void SetObject( int i, void * Obj, runFkt fnct )
{
  ObjektListe[i].obj  = Obj;
  ObjektListe[i].fnct = fnct;
}

und dann meinetwegen
void SetRectangle( int i, rechteck_t * rect )
{
  SetObject( i, rect, runRechteck );
}

void SetTriangle( int i, dreieck_t * drei )
{
  SetObject( i, drei, runDreieck );
}

Autor: Frank Erdrich (erdi-soft)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier gibts ein interessantes PDF zu genau dem Thema:

http://www.planetpdf.com/codecuts/pdfs/ooc.pdf

Nennt sich "Object-Oriented Programming With ANSI-C" und erklärt ganz 
gut, wie man mit C objektorientiert Programmieren kann.

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

Bewertung
0 lesenswert
nicht lesenswert
chris schrieb:
> Vielen Dank für eure Antworten.
>
> Ich sehe ein, dass der Ansatz von KH im Vergleich zum Ansatz von 900ss
> eine schneller Ausführungsgeschwindigkeit bringt. Allerdings bin ich mir
> noch nicht sicher, ob die Objektunterscheidung in der runObject Function
> nicht übersichtlicherwäre, wenn sie über eine case Anweisung
> durchgeführt wird, wie von 900ss vorgeschlagen.

Kann man auch machen.
Der Geschwindigkeitsgewinn ist eigentlich nur eine nette Zugabe.
Viel wichtiger in der Objektorientierung mittels 'virtuellen Funktionen' 
ist es eigentlich, dass man im Nachhinein auch noch andere 
Objekt-Klassen hinzufügen kann, ohne das halbe Programm absuchen zu 
müssen, welcher switch-case wie erweitert werden muss. Wenn man die 
Aufteilung in mehrere *.c Files richtig macht, dann braucht der 
'Verteiler' noch nicht einmal neu kompiliert werden und verteilt 
trotzdem die Run Aufrufe für die neu hinzugekommenen Kreise richtig :-)

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was willst du überhaupt mit verschienden "objecten" in einer Liste? 
Soetwas mach man doch auch in C++ nicht. Dort würden man eine Liste 
Basis-Klasse machen und alle Objecte müssen zu diesen Basisklasse 
konvertierbar sein. Aber eine Liste mit komplett verschienden Objekten 
zu haben nur weil sie eine identische Methode macht doch wenig sinn 
oder?

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

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> was willst du überhaupt mit verschienden "objecten" in einer Liste?
> Soetwas mach man doch auch in C++ nicht.

Der Einwand ist berechtigt :-)
In C++ macht man eine Liste von Pointern auf Objekte. Weil man nur so 
polymorphes Verhalten hinkriegt.
Aber das C-Pendant oben wurde stillschweigend in diese Richtung 
verändert.

> Aber eine Liste mit komplett verschienden Objekten
> zu haben nur weil sie eine identische Methode macht doch wenig sinn
> oder?

Würde ich nicht sagen.
Man kann ja auch den Ansatz vertreten:
Es muss eine Basisklasse, ausgeführt als Interface, geben, welche genau 
diese identische Methode enthält.

Alle Objekte, die in die Liste mit aufgenommen werden möchten, müssen 
dieses Interface implementieren. Ob diese 'Objekte', ausser der 
Unterstützung für dieses Interface auch sonst noch Dinge gemeinsam 
haben, braucht ja die Liste, bzw denjenigen der etwas mit der Liste 
macht, nicht zu interessieren.

Einem Verteiler, der Mausklicks verteilt, soll es doch völlig egal sein, 
ob der Mausklick nun in einem Fenster, einem Objekt-Selektierer oder auf 
einem Pin der parallelen Schnittstelle landet. Ein paar Objekte haben 
sich bei ihm registriert, das entsprechende Interface implementiert und 
kriegen daher Mausklicks zugestellt.

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> was willst du überhaupt mit verschienden "objecten" in einer Liste?

Ich will die "RunFunktion"en der Objekte zyklisch aufrufen. In C++ wäre 
es wohl folgendermaßen zu bewerkstelligen:
for(n=0;n<10;n++)
  ObjektListe[n].RunFunktion();

Aber wie das mit dem Code von KH möglich ist, ist mir nicht ganz klar:
  obj1.fnct( obj1.obj );    // rufe runDreieck indirekt auf
  obj2.fnct( obj2.obj );    // rufe runRechteck indirekt auf
???

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Viel wichtiger in der Objektorientierung mittels 'virtuellen Funktionen'
> ist es eigentlich, dass man im Nachhinein auch noch andere
> Objekt-Klassen hinzufügen kann, ohne das halbe Programm absuchen zu
> müssen, welcher switch-case wie erweitert werden muss. Wenn man die
> Aufteilung in mehrere *.c Files richtig macht, dann braucht der
> 'Verteiler' noch nicht einmal neu kompiliert werden und verteilt
> trotzdem die Run Aufrufe für die neu hinzugekommenen Kreise richtig :-)

Da stimme ich dir zu. Würde jetzt auch eher deine Lösung bevorzugen.

Gruß 900ss

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

Bewertung
0 lesenswert
nicht lesenswert
chris schrieb:
>> was willst du überhaupt mit verschienden "objecten" in einer Liste?
>
> Ich will die "RunFunktion"en der Objekte zyklisch aufrufen. In C++ wäre
> es wohl folgendermaßen zu bewerkstelligen:
>
>
> for(n=0;n<10;n++)
>   ObjektListe[n].RunFunktion();
> 

Das ganz sicher nicht :-)
Wohl schon eher
for(n=0;n<10;n++)
  ObjektListe[n]->RunFunktion();

Für Polymorphismus braucht man in C++ Pointer oder Referenzen.

>
> Aber wie das mit dem Code von KH möglich ist, ist mir nicht ganz klar:
>
  for(n=0; n<10; n++ )
    if( ObjektListe[n].fnct && ObjektListe[n].obj )  // nur zur Sicherheit
      ObjektListe[n].fnct( ObjektListe[n].obj );

Bist du sicher, dass du nicht erst einmal ein paar Wochen 
'konventionelles' C-Training machen solltest, ehe du daran gehst OOP 
Strukturen in C nachzubilden?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> Bist du sicher, dass du nicht erst einmal ein paar Wochen
> 'konventionelles' C-Training machen solltest, ehe du daran gehst OOP
> Strukturen in C nachzubilden?

Und bist du dir weiterhin ganz sicher, dass es partout C sein muss
und nicht doch besser in C++ zu schreiben wäre?

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

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch schrieb:
> Karl heinz Buchegger schrieb:
>
>> Bist du sicher, dass du nicht erst einmal ein paar Wochen
>> 'konventionelles' C-Training machen solltest, ehe du daran gehst OOP
>> Strukturen in C nachzubilden?
>
> Und bist du dir weiterhin ganz sicher, dass es partout C sein muss
> und nicht doch besser in C++ zu schreiben wäre?

LOL
So wie ich das sehe, spielt es für den TO keine allzugroße Rolle. Auch 
in C++ kommt man ohne das entsprechende Wissen nicht weiter. Der Rest 
ist dann einfach nur Programmierer-Handwerk.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> Auch
> in C++ kommt man ohne das entsprechende Wissen nicht weiter.

Das ist richtig, aber die Gefahr, dass man sich mit diesen OO-
Konzepten in C verheddert, finde ich noch größer.  OO in C ist
nun nicht gerade extrem übersichtlich, auch wenn es machbar ist.

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

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch schrieb:
> Karl heinz Buchegger schrieb:
>
>> Auch
>> in C++ kommt man ohne das entsprechende Wissen nicht weiter.
>
> Das ist richtig, aber die Gefahr, dass man sich mit diesen OO-
> Konzepten in C verheddert, finde ich noch größer.  OO in C ist
> nun nicht gerade extrem übersichtlich, auch wenn es machbar ist.

Wohl wahr, wohl wahr.
Zumindest mit Pointern und speziell Funktionspointern sollte man auf 'Du 
und Du' stehen :-) Wenn das nicht sitzt, hat es wenig Sinn die OO 
Schiene in C zu versuchen.

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber, aber, wer wird denn gleich aufgeben? Wenn ich jetzt sage, dass ich 
mindestens seit 15 Jahren ( erfolgreich ) Mikrocontroller in C 
programmiere, werdet Ihr vielleicht lachen.
Allerdings kann man die Verwendung von Pointern auch in C weitestgehend 
reduzieren. Ich versuche, die meine Programme in möglichst einfachem 
Stil zu halten und keine speziellen C-Konstruktionen zu benutzen. Und ob 
Ihr's glaubt oder nicht, damit kommt man ziemlich weit.

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RPM schrieb:
> warum uebergibst du der Funktion "fnct" einen Pointer auf das Object
> selbst?

Ich denke mal, dass sich die Frage von RPM auf dieses Konstrukt bezog:
ObjektListe[n].fnct( ObjektListe[n].obj );
sieht komisch aus, wenn man der Funktion eines Objektes noch mal den 
Pointer auf das Objekt übergeben muss.

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

Bewertung
0 lesenswert
nicht lesenswert
chris schrieb:

> Stil zu halten und keine speziellen C-Konstruktionen zu benutzen. Und ob
> Ihr's glaubt oder nicht, damit kommt man ziemlich weit.

Doch das glaube ich dir.
Aber mit Pointern kommt man dann eben noch etwas weiter :-) bzw. kann 
das Gewünschte effizienter und Laufzeiteffektiver ausdrücken. Man kann 
schliesslich ja auch Arithmetik betreiben ohne je Multiplizieren zu 
müssen. Addieren reicht dicke.

Im Ernst: Funktionspointer sind nur am Anfang gewöhnungsbedürftig. Das 
wichtiste Hilfsmittel bei Funktionspointer ist m.M. ein typedef, mit dem 
man den Datentyp kapselt. Ab dann ist das einfach nur ein Datentyp wie 
ein int oder jeder andere Pointer auch. Wenn man den Pointer 
'dereferenziert', kriegt man keine Daten zurück, sondern eine Funktion 
wird aufgerufen (die natürlich dann auch wieder Daten zurückliefern 
kann). Bei der Zuweisung einer Funktion schreibt man auf der rechten 
Seite den Funktionsnamen ohne () [mit () würde ja die Funktion 
aufgerufen]. Das wars dann auch schon - das sind Funktionspointer.

Und es ist egal, ob man schreibt

    (*fnct)(i);

oder

     fnct(i);

Beide mal wird die Funktion, deren Adresse in fnct abgelegt wurde 
aufgerufen und ihr i mitgegeben. In der ersten Variante sieht man 
vielleicht etwas besser, dass es sich um einen Funktionspointer handelt 
und dass dieser derferenziert werden muss um an die Funktion zu kommen.

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

Bewertung
0 lesenswert
nicht lesenswert
chris schrieb:

> sieht komisch aus, wenn man der Funktion eines Objektes

Tja. Nur gibt es in C so etwas wie 'die Funktion eines Objektes' nicht. 
In C gibt es Funktionen und es gibt 'Objekte' (als Instantieerungen 
einer struct oder union). Aber die beiden Dinge haben nichts miteinander 
zu tun.

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
chris schrieb:

> Allerdings kann man die Verwendung von Pointern auch in C weitestgehend
> reduzieren. Ich versuche, die meine Programme in möglichst einfachem
> Stil zu halten und keine speziellen C-Konstruktionen zu benutzen.

Auch wenn sich da andere Sprachen feige zurueck halten, wuerde ich 
Zeiger nicht als "spezielle C-Konstruktion" bezeichnen. Geruechteweise 
soll das ja auf den heutigen Prozessorkonstruktionen ein ganz normales 
Konstrukt sein...

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo KH,

Deiner Erklärungen sind sehr nüttzlich und helfen mir gut weiter.
Zum Verständnis habe ich den Funktionspointer mal in "methode" 
umbenannt.
Aber so langsam kommen mir Selbstzweifel: Bei der Initialisierung eines 
Objektes ergibt sich folgender Fehler:
typedef void (*methode)( void * );

// generelle Objektstruktur
typedef struct
{
  void * obj;
  methode Run;
}object_t;

.....

int main(void)
{
  dreieck_t drei1;
  object_t obj1 = { drei1, runDreieck }; //../ObjTest.c:: error: incompatible types in initialization

  rechteck_t recht1;
  object_t obj2 = { recht1, runRechteck }; //../ObjTest.c:: error: incompatible types in initialization
  obj1.Run( obj1.obj );    // rufe runDreieck indirekt auf
  obj2.Run( obj2.obj );    // rufe runRechteck indirekt auf
}

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

Bewertung
0 lesenswert
nicht lesenswert
chris schrieb:

> // generelle Objektstruktur
> typedef struct
> {
>   void * obj;
>   methode Run;
> }object_t;


>   object_t obj1 = { drei1, runDreieck }; //../ObjTest.c:: error:
> incompatible types in initialization


Na ja.
Was ist denn das erste Member von object_t

    void * obj;

also ein Pointer.
Und womit wird versucht, diesen Pointer zu initialisieren

    ..... = { drei1  ....

und drei1 ist was?

     dreieck_t drei1;

Ein dreieck_t. Also eine komplette Struktur und kein Pointer.

  object_t obj1 = { &drei1, runDreieck };


( Wie hast du es bloss 15 Jahre auf diesem Level geschafft? Irgendwann 
muss es einem doch zu blöd sein immer nur mit Arrays und Indizes 
rumzuwurschteln. Obwohl: Ich kenne auch jemanden der ein komplettes 
3D-CAD geschrieben hat, indem er 10 Arrays mit double, int, char-Arrays, 
... parallel hatte und ständig Indizes abgleichen musste, also wie wenn 
es keine struct gäbe. Man war der auf diesen Unsinn stolz.

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ein dreieck_t. Also eine komplette Struktur und kein Pointer.
Mist, habe zusehr auf den mir bis zu diesem Thread unbekannten 
Funktionspointer geschielt ...

>Wie hast du es bloss 15 Jahre auf diesem Level geschafft?
Das kommt davon, wenn man einfach unbesehen code von Dir einsetzt ;-)
>
>  dreieck_t drei1;
>  object_vt_t obj1 = { drei1, runDreieck };
>

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

Bewertung
0 lesenswert
nicht lesenswert
chris schrieb:
>>Ein dreieck_t. Also eine komplette Struktur und kein Pointer.
> Mist, habe zusehr auf den mir bis zu diesem Thread unbekannten
> Funktionspointer geschielt ...
>
>>Wie hast du es bloss 15 Jahre auf diesem Level geschafft?
> Das kommt davon, wenn man einfach unbesehen code von Dir einsetzt ;-)

LOL
Ich schreibe auch direkt im hiesigen Foreneditor. Da kommt sowas schon 
mal vor. Dafür gibt es dann ja auch einen Compiler, der sowas nicht 
durchgehen lässt.

Autor: chris (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
>Ich schreibe auch direkt im hiesigen Foreneditor

Alle Achtung, wenn Du das Freihand machst.

Ich habe mal das Programm zusammengefasst und einen Konstruktor und eine 
Delete Funktion für die Objekte gebastelt. Der Konstruktor funktioniert, 
allerdings meckert der Compiler noch ein paar Typkonvertierungen an.
Bei der Delete Funktion bin ich mir noch nicht sicher, ob sie 
funktioniert.
Kann es sein, dass das Speicher freigeben nicht ganz so geht, wie es 
wünschenswert wäre? Ich habe den AVR-GCC verwendet, git es in C sowas 
wie "Garbage Collection"?

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

Bewertung
0 lesenswert
nicht lesenswert
chris schrieb:
  // Objekt mittels Konstruktor erzeugen
  object_t obj3;
  obj3=*new_Rechteck(22, 33); // Achtung: Datenverdoppelung

Vorsicht mit solchen Sachen!
Du hast keinen 'Copy-Konstruktor' der sich darum kümmert und der 
'Destruktor' des temporären Objektes welches zurückgeliefert wird, wird 
auch nicht aufgerufen, weil ist ihn schlicht und ergreifend nicht gibt: 
Memory-Leak

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

Bewertung
0 lesenswert
nicht lesenswert
chris schrieb:

> Kann es sein, dass das Speicher freigeben nicht ganz so geht, wie es
> wünschenswert wäre?

Sollte schon.
Aber dazu musst du auch deine Delete Funktion für alle 'Objekte' 
aufrufen (und solche Spässe wie im vorigen Posting tunlichst vermeiden).

> Ich habe den AVR-GCC verwendet, git es in C sowas
> wie "Garbage Collection"?

Nein.

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.