Objekte nicht funktionsübergreifend verwendbar?
-
Hallo alle mal. Ich bin relativ neu beim progr. dabei und versuche gerade mein erstes "größeres" Projekt zustande zu bringen. Jetzt habe ich allerdings ein problem
ich habe eine funktion in einer klasse, die mir eine reihe von anderen objekten definiert. wenn ich nun aber eine zweite funktion der klasse aufrufe, sind die alten objekte nicht mehr deklariert.
warum nicht?
das ganze sieht in etwa so aus:#include <iostream> #include <string> #include "kontrolle.h" #include "admin.h" using namespace std; void first_first(void) { Admin n_sys, n_tre, n_pro; //hier werden die Objekte erzeugt n_sys.standard("Ort","Name1",0); //hier werden ihnen von einer n_tre.standard("Ort","Name2",0); //anderen Klasse nacheinander n_pro.standard("Ort","Name3",0); //Werte zugewiesen } void first_main(string name, string pw) { n_system.output(); //Aber hier existieren die Objekte n_treibe.output(); //Angeblich nicht mehr..... n_progra.output(); }
-
2 Gründe fallen spontan auf.
- Du erzeugst:
Admin n_sys, n_tre, n_pro;beutzt aber
n_system.output(); //Aber hier existieren die Objekte n_treibe.output(); //Angeblich nicht mehr..... n_progra.output();Das sind völlig verschiedene Variablen. Dies kann also so nicht gehen.
Aber:
- Du hast eh eine "Skope-Problem".
Selbst wenn du die gleich nennen würdest, würde es nicht gehen.
Denn die 3 Admin Objekte die du in der ersten Funktion erzeugst, gibt es auch
nur dort.
Wenn du die 2te Funktion von dort aufrufst, wo die Objekte existieren ( also bei dir in der ersten Funktion ) und ensprechend die Objecte übergibst, kann es gehen.
Oder du rufst output einfach sofort auf.
So oder so,wäre es gut zu wissen, was du vor hast, bevor man vermutet,
wie man dein Konstrukt anpassen könnte.
Auf jeden Fall sind deine 3 Objekte im localen Scope ( der ersten Funktion ) und existieren nicht mehr
sobald du ihn ( also die Funktion ) verlässt
-
shapeless schrieb:
2 Gründe fallen spontan auf.
- Du erzeugst:
Admin n_sys, n_tre, n_pro;beutzt aber
n_system.output(); //Aber hier existieren die Objekte n_treibe.output(); //Angeblich nicht mehr..... n_progra.output();Das sind völlig verschiedene Variablen. Dies kann also so nicht gehen.
Ok stimmt. das war allerdings nur nen fehler den ich hier gemacht hab, weil ich den ganzen code nen bissel gekürzt hab, damits besser lesbar ist.
Aber:
- Du hast eh eine "Skope-Problem".
Selbst wenn du die gleich nennen würdest, würde es nicht gehen.
Denn die 3 Admin Objekte die du in der ersten Funktion erzeugst, gibt es auch
nur dort.
[...]
ok verstehe. ich bin mir da nicht sicher, wie lautet die genaue syntax um objekte zu übergeben? eigentlich muss ich der funktion ja vorher sagen was alles übergeben wird, aber das kann ich nicht machen, wenn ich später noch mehr objekte kreieren will und nich weiß wie viele es sein werden.....
-
Ja, da hast du recht, dies musst du der Funktion übergeben.
Dies wäre ein kleines Beispiel:
#include <iostream> class Admin{ public: Admin(int val): val_(val){} void output()const{std::cout<<val_<<"\n";} private: int val_; }; void print(const Admin & adm){ adm.output(); } void create_and_output(){ Admin foo(1),bar(2),baz(3); print(foo); print(bar); print(baz); } int main(){ create_and_output(); return 0; }Naja, letzendlich musst du ( ohne templates oÄ zu nutzen ) schon wissen,
was du übergeben willst.
Du brauchst aber ggf die 2te Funktion garnicht.
Wie man in meinem Beispiel sehen kann, macht Sie ja nichts, als eine Member
funktion einer Klasse aufzurufen. Dies kannst du natürlich auch einfach
direkt in der ersten tun.
Wenn du aber elegant mehrere ( ungewiss wieviele Objekte ) verwalten möchtest,
bietet es sich natürlich an einen Container zu nutzen.
Dann kannst du beliebig viele Objkte eines Types dort verstauen und über eine
einfache Iteration alle ( in einer helfer funktion der du den Container übergibst ) alle ausgeben.Dann brächstest du aber für jeden Typen ( falls du noch andere Klassen hast )
einen eigenen Container.
Ausser du nutzt einen Container mit Poinern ( zb pointer-vektor ), dann kannst
du auch einen für alles nehmen und dir Polimorphismus zu nutzen machen.
Ich weiss aber nicht, ob du dies kennst oder willst.So oder so denke ich mit Containern ( zB vector ) kannst du ne menge gewinnen.
//edit1
Mit containern würde es dann so ungefähr aussehen können:
#include <iostream> #include <vector> #include <iterator> class Admin{ public: Admin(int val): val_(val){} void output()const{std::cout<<val_<<"\n";} private: int val_; }; typedef std::vector<Admin> admin_container_t; void print(const admin_container_t & container){ for(admin_container_t::const_iterator it=container.begin();it!=container.end();++it) it->output(); return; } void create_and_output(){ admin_container_t admin_container; admin_container.push_back(Admin(1)); admin_container.push_back(Admin(2)); admin_container.push_back(Admin(3)); print(admin_container); } int main(){ create_and_output(); return 0; }Bevor ich aber weiter mache, würde ich gern darauf hinweisen, dass
es ggf keinen Sinn macht Objekte Lokal zu erzeugen, dann von dort aus
diverse andere Sachen zu starten, da deine Funktion sonst zuviel verschiedene
Logik enhtält.
Insgesamt sehe ich nicht den Vorteil, den deine erste Funktion hat bzw Ihren Sinn.
Dies kann aber daran liegen, dass du ja nur ein Fragment gezeigt hast.
Wie dem auch sei. Die Objekte nicht lokal anzulegen ist denke ich sinnvoll,
sobald man diese wiederverwenden möchte.
Aber wie gesagt ohne den echten Inhalt des Programmes zu kennen, kann dazu
natürlich nicht viel sagen.
-
danke erstmal soweit für die ganze hilfe.
also der sinn des programms ist folgender:
ich habe eine datei, die die gesamten funktionen "kontrolliert"
ich hab sie kontrolle.h bzw. kontrolle.cpp genannt//Kontrolle.h #ifndef _KONTROLLE_ #define _KONTROLLE_ class Kontrolle { bool start_einstellungen; std::string name, pw; int was_ich_will; public: void first_first(std::string name, std::string passwort); }; #endif+ Kontrolle.cpp
#include <iostream> #include <string> #include "kontrolle.h" #include "ordneradmin.h" using namespace std; void Kontrolle::first_first(string name, string pw) { Kontrolle kontrolle; Ordneradmin n_system, n_treibe, n_progra; n_system.standard("C:","System",0); n_treibe.standard("Programme","Treiber",0); n_progra.standard("C:","Programme",0); int was_ich_will; for (;;) { cout << "Welchen Ordner wollen sie angezeigt bekommen?" << endl; cin >> was_ich_will; if (was_ich_will == 1) n_system.output(); if (was_ich_will == 2) n_treibe.output(); if (was_ich_will == 3) n_progra.output(); if (was_ich_will == 0 || was_ich_will > 3) break; } }Dann gibt es noch eine Datei, die hier die ganze Zeit aufgerufen wird:
ordneradmin.h#ifndef _ORDNERADMIN_ #define _ORDNERADMIN_ #include <string> using namespace std; class Ordneradmin { string pname, port; int pid; public: bool standard(const string&, const string&, int); void output(void); std::string name, ort; int id; }; #endifund dazugehörige: ordneradmin.cpp
#include <string> #include <iostream> #include "ordneradmin.h" bool Ordneradmin::standard(const string& name, const string& ort, int id) { pname = name; port = ort; pid = id; } void Ordneradmin::output(void) { cout << pname << endl; cout << port << endl; cout << pid << endl; }der sinn des programms ist ungefähr folgender:
die kontroll datei wird am anfang aufgerufen und "erstellt" sozusagen 3 virtuelle ordner mit namen, speicherort und id. danach soll sie diese auf befehl einfach nur wieder ausgeben. natürlich will ich damit im endeffekt noch andere sachen machen, aber ich wollte das erstmal soweit hinbekommen...
natürlich könnte ich auch alles in eine einzige datei machen, aber da das programm ja noch größer wird, hielt ich es für sinnvoll, jetzt schon alles aufzuteilen, damit es alles schön übersichtlich bleibt
der sinn des programms is in etwa, eine festplatte mit dateien, ordnern zu simulieren, die ich dann später natürlich auch umbennen, löschen, etc. möchte. halt wie ein betriebssystem .... findest du meinen ansatz sinnvoll mit dem hintergrundwissen?
Nachtrag: ich habe die ersten beiden funktion in der kontrolle.cpp zusammen in eine gepackt, wie dir sicher aufgefallen ist. (weil du dies ja vorgeschlagen hattest)
-

jetzt funktioniert es.
so wie ich es vorhin gepostet habe
aber trotzdem interessiert es mich natürlich ob du es anders gemacht hättest!!!

-
ich denke, ich hätt schon ein wenig anders gemacht, aber sowas ist auch
oft eine Stilfrage.
Wie dem auch sei, eine Kleinigkeit die noch aufgefall ist, ist die Tatsache,
dass dein "int was_ich_will;" einmal in der Klasse Deklariert wird,
aber dann noch einmal in "Kontrolle.cpp" Zeile 14.
Somit überschattet die lokale int variable deine Klassenvarible.
Dies fällt zwar in deinem Fall nicht auf, ist aber meiner Meinung nach
nicht gewollt.
Ich würde eine Variable, die lediglich an einer Stelle eine Eingabe enthält,
auch lokal lassen.
( Sprich die Klassendeklaration entfernen, sofern du sie nicht noch irgendwo anders benutzt. )
-
ja stimmt hatte ich gar nicht gemerkt.
danke für die schnelle antwort