wie setze ich Funktion die Objekt zurückgibt richtig ein??
-
Ich will Dich ja nicht schocken ;), aber das ganze geht auch so:
#include <iostream> using namespace std; class TMember { public: void ShowIt()const{cout<<"Test"<<endl;} }; class TBase { public: TMember *GetMember(){ return new TMember(); } //TMember-Objekt dynamisch erzeugt }; int main() { TMember *p; TBase *b = new TBase(); //TBase-Objekt dynamisch erzeugt p = b->GetMember(); p->ShowIt(); delete b; // Löschen von b nicht vergessen delete p; // Löschen von p nicht vergessen }
-
Solche Konstrukte würde ich aber versuchen zu vermeiden. Hier vergisst man leicht einmal den zurückgegebenen Pointer zu löschen.
-
damit schockst du mich nich...freut mich eher!
Wenn du mir das noch bissl erklärst....warum grad so....wäre nett!
-
nillables Vorschlag ist zwar richtig, aber total dreckig und wird nur von Anfängern so gemacht.
Im Übrigen willst du eine Factory bauen, so lautet der korrekte Begriff. Weil du da wie in einer Fabrik Objekte baust.
Aber sauberer wäre das hier (um die Kritik von Braunstein hier mit eine Lösung zu vervollständigen):
#include <memory> using namespace std; auto_ptr<TMember> createTMember() { auto_ptr<TMember> obj(new TMember()); return obj; }
Erklärung zum ganzen findet man hier
-
getMember sollte man aber eine Factory nicht gerade nennen. Da "get" eigentlich bedeutet, das man ein Attribut eines Objectes will. Also immer das gleiche und nicht jedes mal ein neues. Wenn dann sollte man es schon createTMember() nennen, dann weiß jeder das bei aufruf dieser Methode/Funktion wirklich jedesmal ein neues TMember erzeugt wird.
-
Manchmal will man eben bei jedem Aufruf ein neues Objekt und nicht immer einen Zeiger auf das gleiche bekommen. Der Name der erstellenden Methode sollte aber dann, wie Artchi richtig bemerkt, eigentlich nicht Get... sein, sondern Create... so wie Du es am Anfang hattest. Wenn man nicht dynamisch eine Instanz erstellt und diese zurückgibt (
TMember t; return t;
), wird das komplette Objekt kopiert und das lokale gelöscht, was man aber manchmal (vor allem bei größeren Objekten) vermeiden will. Das dynamische Erzeugen von Objekten, wird, wie Artchi schon andeutete, häufig gemäß des Entwurfsmusters "Abstrakte Fabrik" realisiert (allerdings selten von Anfängern).
http://de.wikipedia.org/wiki/Abstrakte_Fabrik
-
Für einen Anfänger wäre aber das hier wohl erstmal mal einfacher:
http://de.wikipedia.org/wiki/Fabrikmethode
-
nun bin ich bisschen verwirrt....=/
Also nen totaler anfänger bin ich nicht mehr,sag ich mal...aber eben auch kein profi!
Und mit autopointern habe ich noch NIE gearbeitet
-
Was verwirrt dich denn genau? Verwirrt dich, was eiine Factory ist? Oder die Syntax? Wenn du noch nie Autopointer bzw. allgemein Smartpointer (da gibts neben auto_ptr noch andere) benutzt hast, wird es ja jetzt mal Zeit bzw. es gibt jetzt einen Grund. Denn nur weil man etwas noch nicht benutzt hat, muß man es ja nicht ablehnen.
-
Lass Dich nicht entmutigen! So wild ist das mit den Fabriken nicht. Eine Anwendung der Abstrakten Fabrik kannst Du Dir zum Beispiel so vorstellen:
Es gibt eine abstrakte Klasse Fleischfabrik mit den virtuellen Methoden:- ErstelleWurst
- ErstelleFrikadelle
- ErstelleHackfleisch
Es gibt eine Methode oder Funktion, die mit einem Fleischfabrik-Objekt arbeitet. Je nachdem von welcher Unterklasse der Fleischfabrik ein Objekt übergeben wird, werden Geflügel-, Rind-, Schweine- oder auch Lammfleischprodukte erstellt.
Bei Fabrikmethode gibt es in der abstrakten Klasse ausser virtuellen Methoden auch noch mindestens eine konkrete, die von den virtuellen Gebrauch macht, um Dinge zu erstellen. Bezogen auf das obere Beispiel könnte eine abstrakte Klasse Fleischfabrikmethode noch zusätzlich die konkrete Methode TischleinDeckDich haben, welche dann die jeweiligen Produkte erstellt und damit den Tisch deckt. Wenn es nun eine Methode oder Funktion gibt, die ein Fleischfabrikmethode Objekt erwartet, und die Methode TischleinDeckDich aufruft, wird je nachdem von welche Unterklasse das Objekt ist, der Tisch mit den Produkten, der jeweiligen Fleischsorte gedeckt.
Auto Pointer sind zwar recht praktisch, aber nicht als Container-Elemente geeignet. Hier findest Du eine kurze Beschreibung:
http://www.ica1.uni-stuttgart.de/Courses_and_Lectures/C++/script/node32.html
-
Ich frag mich bloß warum du ihm unbedingt das Fabrik-Pattern erklären willst, wo er doch garnicht danach gefragt hat.
-
es verwirrt mich mehr der syntax, eben aus dem grund, weil ich noch nie mit smart uder autopointern gearbeitet habe!
Allerdings lehne ich sie sicher nicht ab, aber sie scheinen mir etwas kompliziert, vorallem da ich mit normalen pointern schon stress hatte (Funktionszeiger hab ich mir noch nicht angeschaut....)!
Was eine factory ist, kann ich mir schon ungefähr vorstellen..
-
ja, und Volkard hat mal gesagt, mann soll die sich solang aufheben, bis man sie ausversehen verstanden hat
-
Die Syntax hat eigentlich nichts mit autopointer zu tun, sondern eher was mit Templates. Es wäre also nicht schlecht, wenn du dir in deinem C++ Buch anschaust, was ein Template ist.
Kennst du z.B. std::vector? Das ist die gleiche Syntax wie in meinem auto_ptr-Beispiel.
std::vector<TMember> vec; // erstelle Vector vom Typ TMember vec.push_back(new TMember()); // füge ein TMember hinten an
Wenn dir die Container aus C++ noch nicht bekannt sind, dann hast du noch viel zu lernen.
Mit Templates kann man z.b. eine Klasse typisieren, den Typ gibt man halt in den spitzen Klammern an.
Das gleiche ist beim auto_ptr der Fall. Der Autopointer will einfach nur wissen, mit welchem Typ er arbeiten soll.
Was der Autopointer macht, habe ich eigentlich in meinem ersten Posting angegeben und nullable glaub ich auch. Ansonst: besorg dir ein vernünftiges Buch über die STL, damit du nicht andauernd im Netz suchen mußt.
-
also templates hab ich eigentlich schon so bissl:
//template funktion?? template <class t> void swap(t& a,t& b) { t temp=a; a=b; b=temp; } //template klasse?? template <class t> class test { private: t* data; public: test(int /* oder t??? */ size){data = new t[size];} virtual ~test(){delete[] data];} }; //in main test<double> t(5); //so richtig??
nur, um zu zeigen, das ich doch schon bisschen was kann
allerdings mit vector und so hab ich auch noch nix gemacht, weil direkt zu dem thema steht in emeinen büchern nix....
-
Das mit den Templates sieht doch gut aus. Das Problem bei auto_ptr ist auch gewöhnlich nicht die Syntax (grammatikalische Korrektheit), sondern die Semantik. Wenn z. Bsp. ein gültiger auto_ptr a einem auto_ptr b zugewiesen wird (a wird kopiert), dann wird a ungültig.
-
ich glaub das ist ein thema, was ich mir später mal anschaue...ist wohl schon eher expertenthematik!
oder hast gutes tutorial wo soetwas erklärt wird?
-
mann! das problem mit c++ ist, daß die dinge immer viel komplizierter gemacht werden als sie sind.
aber unser was? ist ja noch anfänger! der ist schon froh, wenn er ein programm hinkriegt, das überhaupt funtioniert.
class TMember { public: void ShowIt()const{cout<<"Test"<<endl;} }; class TBase { public: TMember CreateIt(){return TMember(); } // so gehts am einfachsten // ginge aber auch so: // TMember CreateIt(){TMember t; return t;} }; int main(int argc, char* argv[]) { // TBase *b = new Base(); //Base-Objekt erzeugt, und jetzt?? // und jetzt nichts mehr! beim erzeugen eines objekts wird // der konstruktor automatisch aufgerufen. damit erfolgt // hier auch automatisch die ausgabe von "Test". TBase b; // das tuts auch. das praktische an c++ ist, daß man nicht mehr // so viele zeiger braucht. aber nur, wenn man von den // möglichkeiten auch gebrauch macht! return 0; }
du mußt also nicht immer erst eine variable deklarieren, um ein objekt zu erzeugen. mit return TMember(); geht es auch. das geht genauso wie mit dem operator new nur eben ohne new davor. sowas nennt man dann ein temoräres objekt.
-
damit das programm auch erfolgreich kompiliert werden kann mußt du aber noch
#include<iostream> using namespace std;
an den programmanfang setzten. sonst funktioniert die sache mit dem cout nicht.
-
also das mit using namespace std; weiß ich nu schon!
Zu deinen anderen Post...da versteh ich nicht ganz, was das mit meinem problem zu tun hat....du erzeugst doch nur ein Base Objekt aufm Stack und nicht aufm Heap...
Aber es wird doch nciht automatisch ein Member Objekt erzeugt...oder?
hm...