Lupuz.de: Artikel-Portal / Magazin

Zurück   Postpla.net - die Forum Community > PC, Internet und Technik > Coder's Area

[c++] OOP/.h Ringincludes

Anzeigen:

Thema geschlossen
 
Themen-Optionen
El Sparko
Alt 16.05.2007, 15:00   #1
Standard [c++] OOP/.h Ringincludes

Hey Leute,

wie ihr wisst bin ich ja jetzt der ANSI-C crack aber leider programmieren wir ja dieses Semester c++...

Ich habe noch rudimentäre OOP-Knowledge aus Javazeiten und auch mehr oder weniger UML-Klassendiagram-Kenntnisse. Für mein Projekt hab ich also jetzt schön rummodelliert und wir haben angefangen zu Pogrammieren.

Jetzt gibt es einen Streitfall in der Projektgruppe... Irgendwo in den Includes ist ein Fehler und wir haben eine Grundsatzdiskussion.

Von C bin ich es gewohnt includes in die .h zu schreiben und immer schön mit präprozssor "#IFNDEF" sicherzustellen dass sich kein ringinclude bildet...

Unter C++ scheint dies nicht zu gehen. Folgende Beispielsituation:

Klasse Area bindet ein "person.h", da Area sowas wie eine Spielwiese ist und auf dieser Spielwise sollen sich Personen bewegen, d.h auch die Instanzen von Person werden durch Area gespawned.
Klasse Person bindet ein "area.h", den genauen Grund dafür hab ich gerade nicht im Kopf aber nehmen wir an die Person hätte ein Attribut "zugehörige Area" oder sowas... Warum auch immer darüber wollen wir uns erstmal nicht streiten.

Was nun? Laut Aussage meiner Kommilitonen geht so ein Include einfach nicht. Wir müssten also in Person z.b. auf Attribute vom Typ "area" verzichten. Wäre möglich kann aber nicht ideal sein oder?

Ein letzter Ausweg wäre dinge wie die Klasse Person untergeordnet in die Implementierung von Area einzufügen, so ne Unterklasse (nicht Vererbung) oder wie man das nennen will. Find ich aber auch wieder nicht ideal.

Was sagen die Experten? Wie ist der richtige Ansatz aus Sicht der OOP?
 
 
Nach oben
ANSI Lady
Alt 16.05.2007, 15:26   #2
Standard

Vielleicht versteh ich mal wieder alles falsch...

http://www.c-plusplus.de/forum/viewt...s-1279042.html

?
 
 
Nach oben
Wodar Hospur
Alt 16.05.2007, 16:43   #3
Standard

So wie ich das Problem verstehe kann nicht gegenseitig inkludiert werden.

Gegeben ist ein Container:

Code:
#pragma once
#include "obj.h"

class container
{
  public:
   obj* operator=(obj copy);
   obj* operator[](int index);
  private:
   obj* first;
   obj* last;
};
Dieser Container enhält einfach mal ... objects:
Code:
#pragma once
#include "container.h"
#include <string>

class obj
{
  public:
   std::string name;   
  private:
   obj* next;
   container* cont;
};
Bei dem Versuch das zu Übersetzen gibt mir der Visual C++ und der GCC lustige Synatxfehler.

Allerding:
Code:
#pragma once
#include <string>


class obj
{
  public:
   std::string name;   
  private:
   obj* next;
   container* cont;
};


class container
{
  public:
   obj* operator=(obj copy);
   obj* operator[](int index);
  private:
   obj* first;
   obj* last;
};
kompiliert er ohne Murren. Ich selber habe leider auch keine passende Lösung gefunden, auch wenn dieser Fall allerdings eher selten auftritt, da eine wechselseitige Beziehung selten ist.

Falls nur auf Methoden der Klasse zugegriffen werden muss, kann das Einfügen aber auch notfalls erst bei der Implementierung erfolgen.
 
 
Nach oben
El Sparko
Alt 16.05.2007, 19:00   #4
Standard

@ansi: nein präprozessor makros sind nicht das problem. das problem ist dass trotz der makros wenig hilfe für den vorliegenden fall gegeben wird, ganz einfach weil c++ genauso wie c leider jedes dämliche object einzeln kompiliert.

wir haben jetzt auch schon ne anfrage an prof gestellt... glaub aber nicht dass da viel dabei rum kommt.

ne wirklich extrem hässliche alternative wäre die steuerung zwischen den klassen in ne mehr prozedural orientierte dämliche main() zu schreiben aber dagegen weiger ich mich noch. ich will OOP machen und nicht structs zu klassen aufblasen, um dann doch prozedural vorzugehen. da hät ich auch bei ansi c bleiben können.
 
 
Nach oben
El Sparko
Alt 18.05.2007, 00:23   #5
Standard

unser prof hat uns jetzt auf die frage hin wie das denn gehen soll gesagt man möge doch die klassen, die benutzt werden sollen vorher nochmal deklarieren...

heist im endeffekt schreibst im container nochmal TROTZ INCLUDE "class object;"... sollte gehen. das projekt ist aber zu komplex um das jetzt testen zu können. wir sind noch tage von der kompilierbarkeit entfernt.

mittlerweile verfluche ich aber c++. es scheint auch rein garnichts vom OOP ansatz umsetzbar zu sein. wir streiten mittlerweile sogar schon wie man referenzen übergibt. es scheint nichts mehr zu funktionieren. und da sagt man pointerarithmetik wäre zu komplex. pointer sind einfach und sinnvoll im gegensatz zu de c++-scheißdreck... echt hey.

folgendes:

wir haben jetzt ne klasse "Person" und die hat ein attribut "Area& associatedArea". das ist doch ne referenz oder? also übergeben wir im konstruktor ne referenz der zugehörigen Area. Das zuweisen mit operator "=" geht aber nicht. wahrscheinlich muss man hierfür einen ganz komplizierten copy-constructor oder ähnliches entwerfen. das kann und will ich nicht. unser prof schwafelt immer vom standardkontruktor und was weiß ich noch alles... es muss doch möglich sein ne scheiß dämliche referenz auf etwas zu speichern ohne dass ich jetzt anfange objekte irgendwie mit memcpy und 20 konstruktoren zu bearbeiten.
 
 
Nach oben
Wodar Hospur
Alt 18.05.2007, 01:33   #6
Standard

Warum soll denn die Eigenschaft associatedArea eine Referenz sein? Prinzipiell sind Referenzen halt eintfacher zu handhaben, da nichts umgestellt werden muss, der Entwickler legt fest ob er eine Referenz will oder nur eine Kopie. Beim benutzen entfällt dadurch das referenzieren und derefernzieren. Sprich später weniger Aufwand.

Ansonsten gibt es ja noch paar andere hübsche Dinge bei C++ (Templates, Mehrfachvererbung,...).
 
 
Nach oben
El Sparko
Alt 18.05.2007, 04:14   #7
Standard

templates ja... die verwenden wir ja auch schon ganz heldenhaft um alles nach alles zu casten. das ist ja nicht das problem. wir wissen schon was es bei c++ gibt und eben auch dass referenzen const pointer sind. am wissen mangelts nicht, man bekommt schon ordentlich den kopf aufgeblasen in den vorlesungen.

associatedArea MUSS übriegens ne referenz sein, weil ich wohl kaum das ganze Area objekt kopieren möchte... das wird nämlich ziemlich groß zur laufzeit. was muss man tun um consts zu initialisieren? genau die gute alte initialisierungsliste... funktioniert nun also auch. wir nähern uns der kompilierbarkeit.
 
 
Nach oben
El Sparko
Alt 22.05.2007, 09:55   #8
Standard

nur mal ein statusupdate... wir bewegen uns wie gewohnt an den grenzen von c++. wir haben durch diese container-unterobjekt-beziehung jetzt ringincludes und diese weitestgehend durch vorwärtsdeklarationen kompilierbar gemacht. alle .h dateien haben auch compileguards (hatten wir auch ohne c++ schon standardmässig drin)... leider stoßen wir jetzt an die grenze von c++. es geht wohl nicht in einer klasse unterobjekte zu haben, die vererbung haben...

so ungefähr:

container -> unterobjekt A -> unterobjekt B (vererbt von A, sprich "B ist ein A")
 
 
Nach oben
Lupus Silvanus
Alt 22.05.2007, 10:09   #9
Standard

Krass, ist das echt die Standard-Vorgehensweise?

Container mit Unterobjekten, die den Container kennen ist doch ne ziemlich häufige Situation.

Ähm, mal ne Idee: haut das hin wenn die Unterobjekte nicht den Container kennen, sondern nur eine Superklasse von ihm?

Also sowas wie:
* Spielwiese erbt von Landschaft
* Leute, Bäume und Ufos sitzen auf der Spielwiese, kennen aber nur die Landschaft

dann haben wir:
* Spielwiese includiert Landschaft
* Spielwiese includiert Leut, Baum und Ufo
* Leut, Baum und Ufo includiert jeweils Landschaft

Die Überlegung daran ist ganz klassisch OOP-mäßig dass die Objekte auf der Wiese nicht jedes Detail der Wiese kennen müssen, alles was für die Unterobjekte wichtig ist wandert in der Vererbungshierarchie nach oben.
damit haben wir die Kreiselbeziehung in ein Dreieck aufgebrochen.

Sparko, wär super wenn du kurz sagst ob und / oder wie das in C++ hinhaut, und welche Klasse dann wirklich was includet, weil ich selber kein c+ kann.
 
 
Nach oben
Wodar Hospur
Alt 22.05.2007, 11:08   #10
Standard

Was du gerade angesprochen hast passt schon Sparko. Allerdings musst du dann afaik per virtual das ganze etwas abkoppeln und später dann per Late Binding realisieren. Sprich Methoden werden erst zur Laufzeit auf das Objekt bezogen. Aber da muss ich mich vorher auch mal kurz schlau machen. Ich weiß das es gehen SOLL.
 
 
Nach oben
El Sparko
Alt 22.05.2007, 15:53   #11
Standard

wir haben von nem professionellen coder jetzt ne mögliche lösung bekommen... alle header includes in einer einzelnen .h und diese z.b. in der main.cpp includen. der rest im code nur vorwärtsdeklaration. bin gespannt was daraus wird. melde mich wieder.

-edit: tja wär zu einfach gewesen... ich bekomms auch mit der lösung nicht hin, da vorwärtsdeklaration nicht überall ausreichend ist. z.B. wenn man die STL benutzt und dann z.b. ne <objekt>list machen möchte.

langsam bin ich echt ratlos. wahrscheinlich müssen wir das ganze projekt aufdröseln und sowohl auf vererbung wie auch auf großartige unterteilung in klassen verzichten. c++ schaffts einfach nicht, zumindest nicht für normalsterbliche verständlich.

Geändert von El Sparko (22.05.2007 um 22:40 Uhr).
 
 
Nach oben
El Sparko
Alt 26.05.2007, 03:46   #12
Standard

Zitat von El Sparko
langsam bin ich echt ratlos. wahrscheinlich müssen wir das ganze projekt aufdröseln und sowohl auf vererbung wie auch auf großartige unterteilung in klassen verzichten. c++ schaffts einfach nicht, zumindest nicht für normalsterbliche verständlich.
um mich hier nochmal zu melden. diesen Donnerstag konnten wir unseren abgabetermin natürlich nicht einhalten, weil ums verrecken kein compile durchgelaufen ist und weil sich, nachdem ich auf vererbung radikal verzichtet hatte und dabei war die includes wieder oldschool umzubauen bemerkt habe wie viel mist auf der strecke geblieben ist. ich will jetzt nicht ins detail gehen aber für mich hört das teamwork einfach auf wenn leute ihre klassen als fertig bezeichnen ohne jemals einmal durchkompiliert zu haben weil sie ihrerseits darauf verweisen die andere klasse vom anderen entwickler wäre ja schließlich auch nicht durchgelaufen.

ich hab also jetzt genügend erfahrung mit CAL (code anderer leute) und wir sind wenigstens auf den konsenz gekommen jetzt keine schwierigen gebiete mehr anzufangen. alles wird so simpel wie möglich zusammengeschustert und wir verzichten, ausser auf klassen, auf so ziemlich jedes feature von c++. die objektorentierung mag eine tolle philosophie sein aber es ist einfach mit c++ nicht managebar und nicht verständlich umsetzbar und vorallem war es die dämlichste idee überhaupt von stoustrup zu glauben man müsse unbedingte kompatibilität mit dem unglaublich unterirdischen c-compiler beibehalten.

wenn ich die scheiße hinter mir habe werde ich mich privat eher mal mit D auseinandersetzen aber c++ kommt mir nicht mehr aufn tisch... c ist schlüssig und logisch, java eventuell auch (da hat ich noch nie solche probleme), aber c++ ist einfach nur gepatchte scheiße und absolut nicht das was man 2007 von einer programmiersprache erwartet.
 
 
Nach oben
Anzeigen:
Thema geschlossen

Lesezeichen

Themen-Optionen



Alle Zeitangaben in WEZ +2. Es ist jetzt 04:00 Uhr.


Lupuz.de - wir können auch anders!
©1998 - 2008, Lupuz:Information-Network
Powered by vBulletin Version 3.7.1 (Deutsch), Jelsoft Enterprises Ltd.
Grüne Links?

SEO by vBSEO 3.2.0 ©2008, Crawlability, Inc.