23. august 2004 - 23:12
Der er
10 kommentarer
En rigtig hård banan !
Er der en hård banen her som kan hjælpe mig med at se hvad der er galt i den her? #include <iostream> #include <string> #include <vector> #include <map> #include <windows.h> #include <stdlib.h> #include <typeinfo.h> using namespace std; class Argument { private: public: //protected: Argument* m_pChild; int m_iLenArg; std::string m_strTypeName; public: Argument(void) : m_pChild(0) { } //copy construktor Argument(const Argument& rhs) : m_pChild(0) { } Argument operator << (Argument pChild) { setChild(&pChild); return *this; } Argument* operator << (Argument* pChild) { setChild(pChild); return this; } void setChild(Argument* pChild) { m_pChild = pChild; } Argument* getChild() { return m_pChild; } Argument* getChildPtr() { return m_pChild; } }; template <class T> class TArgument : public Argument { private: T* m_pContainer; public: TArgument(T arg) { m_pContainer = new T; memcpy(m_pContainer, (const void*)&arg, sizeof(T)); m_iLenArg = sizeof(T); m_strTypeName = std::string(typeid(T).name()); } }; class ArgumentList { private: Argument* m_pRoot; public: ArgumentList(Argument root) { m_pRoot = &root; } int count() { int i=0; Argument* pArg = m_pRoot; while(pArg) { i++; pArg = pArg->getChildPtr(); } return i; } }; void function(ArgumentList arglist) { cout << arglist.count() << endl; } void main() { function( ArgumentList( TArgument<int>(32) << TArgument<std::string>("hey") ) ); }
Annonceindlæg fra DE-CIX
23. august 2004 - 23:13
#1
hvad synes man forresten om ideen ?
23. august 2004 - 23:51
#2
Der er faktisk 2 fejl. Fejl 1: Den her er helt forkert: //copy construktor Argument(const Argument& rhs) : m_pChild(0) { }
24. august 2004 - 00:05
#3
Faktisk tror jeg at fejl 2 er næsten det samme som fejl 1. Der sker noget grimy når Argument instanserne bliver destrueret !
24. august 2004 - 00:08
#4
>krismort, du har ret i at det er en hård banan, så lad mig svare på dit andet spørgsmål: Jeg synes ikke om ideen. Specielt synes jeg ikke om at tage et kopi af en std::string, som du gør i TArgument construktoren.
24. august 2004 - 00:26
#5
Følgende ser ud til at køre: #include <iostream> #include <string> #include <vector> #include <map> #include <windows.h> #include <stdlib.h> #include <typeinfo.h> using namespace std; class Argument { private: public: //protected: Argument* m_pChild; int m_iLenArg; std::string m_strTypeName; public: Argument(void) : m_pChild(0), m_strTypeName("Unknown") { } //copy construktor //Argument(const Argument& rhs) //{ // m_pChild = (Argument *)&rhs; //} Argument &operator << (Argument &pChild) { setChild(&pChild); return *this; } void setChild(Argument* pChild) { m_pChild = pChild; } Argument* getChild() { return m_pChild; } Argument* getChildPtr() { return m_pChild; } }; template <class T> class TArgument : public Argument { private: T m_pContainer; public: TArgument(T arg) { m_pContainer = arg; m_iLenArg = sizeof(T); m_strTypeName = std::string(typeid(T).name()); } }; class ArgumentList { private: Argument* m_pRoot; public: ArgumentList(Argument &root) { m_pRoot = &root; } int count() { int i=0; Argument* pArg = m_pRoot; while(pArg) { i++; cout << pArg->m_strTypeName << endl; pArg = pArg->getChildPtr(); } return i; } }; void function(ArgumentList arglist) { cout << arglist.count() << endl; } void main() { TArgument<std::string>SA("hey"); function( ArgumentList( TArgument<int>(32) << SA) ); }
24. august 2004 - 00:28
#6
Jeg var nødt til at flytte std::string argumentet ud af kaldet til ArgumentList constructoren, hvilket ødelægger ideen.
24. august 2004 - 00:48
#7
En lettere forbedret version hvor kaldet er lidt mere som ønsket, men det er stadig ikke kønt: #include <iostream> #include <string> #include <vector> #include <map> #include <windows.h> #include <stdlib.h> #include <typeinfo.h> using namespace std; class Argument { private: public: //protected: Argument* m_pChild; int m_iLenArg; std::string m_strTypeName; public: Argument(void) : m_pChild(0) { } //copy construktor Argument(const Argument& rhs) { m_pChild = rhs.m_pChild; m_iLenArg = rhs.m_iLenArg; m_strTypeName = rhs.m_strTypeName; } Argument &operator << (Argument *pChild) { setChild(pChild); return *this; } void setChild(Argument* pChild) { m_pChild = pChild; } Argument* getChild() { return m_pChild; } Argument* getChildPtr() { return m_pChild; } }; template <class T> class TArgument : public Argument { private: T m_pContainer; TArgument(TArgument &rhs) { cout << "Oh-no" << endl; } public: TArgument(T arg) { m_pContainer = arg; m_iLenArg = sizeof(T); m_strTypeName = std::string(typeid(T).name()); } }; class ArgumentList { private: Argument* m_pRoot; public: ArgumentList(Argument &root) { m_pRoot = &root; } int count() { int i=0; Argument* pArg = m_pRoot; while(pArg) { i++; cout << pArg->m_strTypeName << endl; pArg = pArg->getChildPtr(); } return i; } }; void function(ArgumentList arglist) { cout << arglist.count() << endl; } int main() { function(ArgumentList( TArgument<int>(32) << &TArgument<std::string>("hey"))); }
24. august 2004 - 01:01
#8
Bemærk at TArgument har fået en instans af T og ikke en pointer til en T, hvilket forbedrer metoden en del. Problemet er så at få hevet data ud fra listen igen.
24. august 2004 - 23:49
#9
En anden løsning, der dog også har sine svagheder. Specielt ville jeg gerne bruge referencer i "ArgListClass operator << ...", så man slipper for at kopiere hele listen, men det vil g++ ikke oversætte #include <iostream> #include <vector> #include <string> class ArgClass { public: enum ArgTypeEnum { IntType, StringType }; ArgClass(int aI) : i(aI), ArgType(IntType) {} ArgClass(std::string aS) : S(aS), ArgType(StringType) {} int i; std::string S; ArgTypeEnum ArgType; }; std::ostream &operator << (std::ostream &os, const ArgClass &aArg) { if(aArg.ArgType == ArgClass::IntType) os << aArg.i; else os << aArg.S; return os; } class ArgListClass : public std::vector<ArgClass> { }; ArgListClass operator << (ArgListClass aList, ArgClass aArg) { aList.push_back(aArg); return aList; } void Func(ArgListClass aArgList) { for(ArgListClass::iterator idx = aArgList.begin(); idx != aArgList.end(); ++idx) std::cout << *idx << " "; } int main() { Func(ArgListClass() << 1 << 2 << 4 << std::string("Ole")); }
26. august 2004 - 20:50
#10
En lidt kønnere version, hvor operatoren bruger referencer. Den viser samtidig hvordan man kan misbruge mutable keyword'et: #include <iostream> #include <vector> #include <string> class ArgClass { public: enum ArgTypeEnum { IntType, StringType }; ArgClass(int aI) : i(aI), ArgType(IntType) {} ArgClass(std::string aS) : S(aS), ArgType(StringType) {} int i; std::string S; ArgTypeEnum ArgType; }; std::ostream &operator << (std::ostream &os, const ArgClass &aArg) { if(aArg.ArgType == ArgClass::IntType) os << aArg.i; else os << aArg.S; return os; } class ArgListClass { public: mutable std::vector<ArgClass>List; }; const ArgListClass &operator << (const ArgListClass &aList, ArgClass aArg) { aList.List.push_back(aArg); return aList; } void Func(const ArgListClass aArgList) { for(std::vector<ArgClass>::const_iterator idx = aArgList.List.begin(); idx != aArgList.List.end(); ++idx) std::cout << *idx << " "; } int main() { Func(ArgListClass() << 1 << 2 << 4 << std::string("Ole")); }
Kurser inden for grundlæggende programmering