Typ aus Datei lesen und in Klasse speichern
-
Bigmek schrieb:
Dazu gibts ja template nur wie ich das dann in eine Liste/array oder sonst wo hineinbekomme weis ich nicht, da ja nicht die ganze Liste den gelichen Datentyp hatt
Und genau da haben wir das Problem. Eine Liste kann nur einen Datentyp aufnehmen. Du kannst nicht verschiedene Datentypen in eine Liste setzen. Ausser du verwendest eben Techniken wie Boost.Any oder Boost.Variant.
Templates bringen dir dabei auch nichts, weil Templates zur Kompilezeit ausgewertet werden. Zur Laufzeit kann man diese nicht auswerten lassen.Grüssli
-
FreakY<3Cpp schrieb:
Darf ich mal fragen wieso du char* statt string benutzt ? Immerhin sind wir hier im C++ Forum

dann halt string, hab das ja nur als beispiel geschrieben, und das sind die ersten zwei datentypen die mir einfallen wenn ich an c++ denke.

und wenn ichs mit einer überladenen funktionmachen
beispiel:
class attribute { ... virtual void getData(); } class attribute_INT : attribute { ... int getData(); } class attribute_STRING : attribute { ... string getData(); } class CType { public: CType(...){...}; char* GetName(); private: char* name; attribute* nextAttribute; }würde das funktionieren?
sorry kann es selber gerade nicht testen
-
Bigmek schrieb:
würde das funktionieren?
Nein, die Rückgabewerte sind nicht identisch, sowas geht nicht.
Grüssli
PS: wtf?
char*kommt dir als erstes bei C++ in den Sinn?
-
const char* ist gar nicht mal so dumm!
es ist eher andersrum, daß 20% der verwendungen von std::string als dumm einzustufen sind, als anfängerfehler im besten fall, aber meistens als ignoranz- und faulheitsfehler. ich nenne nur mal einen klassikerconst string config_filename="myapp.ini";
-
Dravere schrieb:
PS: wtf?
char*kommt dir als erstes bei C++ in den Sinn?
What tha fuck hab ich auch gedacht
Is pures C...Naja aber was du da versucht hast is quatsch und bringt nix.
Allgemein weiss ich noch immer nicht, wie genau du dir das vorstellt, funktionalitätsmäßig. Zeig mal was, dann kann man bestimmt noch besser helfen, weil mir die Deklaration deiner Klasse nicht viel bringt.
-
nein char aber da char nur ein Zeichen ist hab ich char* geschrieben
außerdem hab ich gesagt die ersten Datentypen und nicht das erste.
man kann ja irgendwie den datentyp einer variable abfragen aber ich weis nichtmeh wie, es war irgendwas mit type...class a { }; class a_int : a { public: int data; }; class a_string : a { public: string data; }; a test = new a_string(); ... switch(type...(test)) { case a_string: //tu was ein string so macht break; ... } ...das schaut vielversprächend
FreakY<3Cpp:
ich kann noch nichts zeigen da sich das noch im ideen Status befindet.
und die xml Struktur hast ja gesehen, ich möchte typen aus einer XML datei laden.
-
#include <iostream> int main() { double double_number = 5; std::cout << typeid(double_number).name(); }Damit kriegste auf die Konsole ein "d" geschrieben. So kannste z.B. in deiner Switch-Abfrage auf i,d,c,f etc. prüfen.
-
danke genau das habe ich gemeint.
aber das funktioniert nicht so recht#include <iostream> #include <typeinfo> using namespace std; class a { public: char name; virtual ~a(){}; }; class a_int : public a { public: int data; }; class a_char : public a { public: char data; }; int main(void) { a* test = new a_int(); a_int* test2 = new a_int(); cout<<typeid(test).name()<<endl; cout<<typeid(test2).name()<<endl; delete test2; delete test; return 0; };ausgabe:
P1a
P5a_intder gibt mir a aus sollte aber eigentlich a_int sein ????
edit:
haha DANKE es funktioniertes gehört cout<<typeid(*test).name()<<endl;
anstat cout<<typeid(test).name()<<endl;dann gehts juhu
-
edit: ...
-
Bigmek schrieb:
der gibt mir a aus sollte aber eigentlich a_int sein ????
Nein, der Standard sagt nur, dass die Funktion name() einen lesbaren Namen ausgeben soll. Was das genau ist, wird nicht definiert. Ich glaube er kann sogar für die gleiche Klasse mehrere Unterschiedliche Namen ausgeben. Ein Prüfung auf den Typ ist nur möglich durch den
operator ==destype_infoObjektes.
http://www.cplusplus.com/reference/std/typeinfo/Sag mal, wieso glaubst du mir nicht einfach? Schau dir doch mal Boost.Any oder Boost.Variant zumindest an

Es gibt schon gewisse Möglichkeiten, aber die gehen eben über Boost.Any und Boost.Variant oder dergleichen.Ich habe selber erst gerade sowas benötigt. Hier mal einen Auszug, wie ich das bei mir probiert habe zu lösen. Node ist ein Container für beliebige Objekte, welche ein bestimmtes Konzept erfüllen.
Ist allerdings noch in der Entwicklung.////////////////////////////////////////////////////////////////////////// // Node class Node : public ChildNode { // Static functions // private: template<typename ContentT> static void* copy_content(void* ptr); template<typename ContentT> static void delete_content(void* ptr); // Typedefs // private: typedef void* (*CopyFunction)(void*); typedef void (*DeleteFunction)(void*); // Attributes // private: NodeType m_type; void* m_content; CopyFunction m_copyFunction; DeleteFunction m_deleteFunction; Node* m_prevNode; Node* m_nextNode; // Constructors & Destructor // public: template<typename ContentT> Node(ContentT const& content); Node(Node const& node); ~Node(); // Operators // public: Node& operator =(Node const& node); // Methods // private: template<typename ContentT> void create_content(ContentT const& content); public: NodeType get_type() const; bool is_type(NodeType type) const; template<typename ContentT> bool is_type() const; template<typename ContentT> ContentT* get_content(); template<typename ContentT> ContentT const* get_content() const; template<typename ContentT> void set_content(ContentT const& comment); Node* get_prev_node(); Node const* get_prev_node() const; Node* get_next_node(); Node const* get_next_node() const; template<typename ContentT> void insert_prev(ContentT const& content); template<typename ContentT> void insert_next(ContentT const& content); std::auto_ptr<Node> remove(); void swap(Node& node); }; /************************************************************************/ /* Static methods */ /************************************************************************/ template<typename ContentT> void* Node::copy_content(void* ptr) { return new ContentT(*static_cast<ContentT*>(ptr)); } /************************************************************************/ template<typename ContentT> void Node::delete_content(void* ptr) { delete static_cast<ContentT*>(ptr); } /************************************************************************/ /* Constructor */ /************************************************************************/ template<typename ContentT> Node::Node(ContentT const& content) : ChildNode(content) , m_type(ContentT::NODE_TYPE) , m_content(nullptr) , m_copyFunction(©_content<Comment>) , m_deleteFunction(&delete_content<Comment>) , m_prevNode(nullptr) , m_nextNode(nullptr) { create_content(content); } /************************************************************************/ /* Methods */ /************************************************************************/ template<typename ContentT> void Node::create_content(ContentT const& content) { ContentT* contentPtr = new ContentT(content); contentPtr->set_node(this); m_content = contentPtr; } /************************************************************************/ template<typename ContentT> bool Node::is_type() const { return ContentT::NODE_TYPE == m_type; } /************************************************************************/ template<typename ContentT> ContentT* Node::get_content() { if(is_type<ContentT>()) { return static_cast<ContentT*>(m_content); } return nullptr; } /************************************************************************/ template<typename ContentT> ContentT const* Node::get_content() const { if(is_type<ContentT>()) { return static_cast<ContentT*>(m_content); } return nullptr; } /************************************************************************/ template<typename ContentT> void Node::set_content(ContentT const& content) { (*m_deleteFunction)(m_content); create_content(content); m_copyFunction = ©_content<ContentT>; m_deleteFunction = &delete_content<ContentT>; m_type = ContentT::NODE_TYPE; } /************************************************************************/ template<typename ContentT> void Node::insert_prev(ContentT const& content) { BasicNodeList* container = get_container(); if(nullptr == container) { throw NodeException("No container available, " "can't insert node!"); } if(m_prevNode) { Node* insertNode = new Node(content); insertNode->set_parent(get_parent()); insertNode->set_container(container); insertNode->m_prevNode = m_prevNode; insertNode->m_nextNode = this; m_prevNode->m_nextNode = insertNode; m_prevNode = insertNode; } else if(m_nextNode) { insert_next(content); swap(*m_nextNode); } else { Node* insertNode = new Node(content); insertNode->set_parent(get_parent()); insertNode->set_container(get_container()); insertNode->m_prevNode = nullptr; insertNode->m_nextNode = this; m_prevNode = insertNode; if(container) { container->m_firstNode = insertNode; } } } /************************************************************************/ template<typename ContentT> void Node::insert_next(ContentT const& content) { BasicNodeList* container = get_container(); if(nullptr == get_container()) { throw NodeException("No container available, " "can't insert node!"); } if(m_nextNode) { Node* insertNode = new Node(content); insertNode->set_parent(get_parent()); insertNode->set_container(container); insertNode->m_prevNode = this; insertNode->m_nextNode = m_nextNode; m_nextNode->m_prevNode = insertNode; m_nextNode = insertNode; } else if(m_prevNode) { insert_prev(content); swap(*m_prevNode); } else { Node* insertNode = new Node(content); insertNode->set_parent(get_parent()); insertNode->set_container(container); insertNode->m_prevNode = this; insertNode->m_nextNode = nullptr; m_nextNode = insertNode; if(container) { container->m_lastNode = insertNode; } } }Vielleicht hilft es ja etwas.
Grüssli
-
Wenn sich die Daten als String serialisieren lassen, reicht es doch eine Liste von Strings zu nutzen, und sie mit einer Templatefunktion verfügbar zu machen.
Dabei hilf boost::lexical_cast<T> sehr.So habe ich es gemacht.
-
danke an alle, ich werde es wohl mit typeid machen da mir das das einfachste scheint.
-
Bigmek schrieb:
danke an alle, ich werde es wohl mit typeid machen da mir das das einfachste scheint.
Ich hoffe allerdings, dass du gelesen hast, dass man den Rückgabewert von
name()nicht verwenden darf! Und wieso eine fertige Klasse nicht einfacher ist, als selber was zu bauen, das leuchtet mir nicht so ein
Grüssli
-
volkard schrieb:
const char* ist gar nicht mal so dumm!
es ist eher andersrum, daß 20% der verwendungen von std::string als dumm einzustufen sind, als anfängerfehler im besten fall, aber meistens als ignoranz- und faulheitsfehler. ich nenne nur mal einen klassikerconst string config_filename="myapp.ini";Das stimmt. Aber das "als Anfängerfehler im besten Fall" musst du schon beachten - lieber, man macht etwas von Anfang an richtig. Sehr viele Anfänger haben grosse Mühe mit Zeigern und folglich auch Zeichenkettenverwaltung im C-Stil. Allerdings ist es schade, dass einige Leute sich auch nach besserer Kenntnis von C++ nur noch mit
std::stringrumschlagen, weil sie nichts anderes kennen.FreakY<3Cpp schrieb:
Dravere schrieb:
PS: wtf?
char*kommt dir als erstes bei C++ in den Sinn?
What tha love hab ich auch gedacht
Is pures C...Das bedeutet nicht, dass es in C++ grundsätzlich unberechtigt ist. Also pass mit solchen Pauschalisierungen auf.