Dead_Rabbit Skrevet 31. desember 2004 Del Skrevet 31. desember 2004 (endret) Helleu! Driver å fikler med en reference count, og jeg får en del problemer. Sitter fortsatt på Windows med MinGW kompilatoren. PS: Jeg slo sammen alle filene. Lettere med copy-paste. #include <iostream> template<class T> class RefCount { public: //Consturctors RefCount(); RefCount(const T& new_value); RefCount(const RefCount& new_value); //Destructor ~RefCount(); //General interface RefCount& make_unique() const; RefCount& clone() const; T* memory(); T& operator->(); RefCount& operator=(RefCount&); T& operator=(T&); T& operator=(T); private: T* p; std::size_t* refptr; }; //RefCount #endif //Constructors, destructors template<class T> RefCount<T>::RefCount() { p = new T; refptr = new size_t(1); } template<class T> RefCount<T>::RefCount(const T& rep) { if(&rep != p) { if(!*refptr--) delete p; *refptr--; *this = rep; } } template<class T> RefCount<T>::RefCount(const RefCount& rep) { if(!refptr) { refptr = rep.refptr; ++refptr; p = rep.p; } } template<class T> RefCount<T>::~RefCount() { if(!*(--refptr)) { delete refptr; delete p; p = 0; } else { delete p; p = 0; } } //General interface template<class T> RefCount<T>& RefCount<T>::make_unique() const { return new T(p); } template<class T> RefCount<T>& RefCount<T>::clone() const { return new RefCount(*this); } template<class T> T* RefCount<T>::memory() { return p; } template<class T> T& RefCount<T>::operator->() { return *p; } template<class T> RefCount<T>& RefCount<T>::operator=(RefCount<T>& rhs) { if(!this == &rhs) { if(p != rhs->p) RefCount(); else { this = &rhs; refptr++; } } return this; } template<class T> T& RefCount<T>::operator=(T& rhs) { this = &RefCount<T>(rhs); return p; } using namespace std; int main() { RefCount<int> a; a = 10; RefCount<int> b(a); RefCount<int> c(10); cout << a.memory() << endl; cout << b.memory() << endl; cin.get(); return 0; } Errors: C:\dev\library\common>g++ ref.cpp -o ref.exe C:\DOCUME~1\STLE~1\LOKALE~1\Temp/cc5Mdaaa.o(.text+0x18a):ref.cpp: undefined refe rence to `RefCount<int>::operator=(int)' C:\DOCUME~1\STLE~1\LOKALE~1\Temp/cc5Mdaaa.o(.text$_ZN8RefCountIiEC1ERKi+0x43):re f.cpp: undefined reference to `RefCount<int>::operator=(int)' collect2: ld returned 1 exit status Nok en edit: Oppdatert, igjen... Endret 1. januar 2005 av zirener Lenke til kommentar
saboi Skrevet 31. desember 2004 Del Skrevet 31. desember 2004 (endret) har ikke sett så veldig nøye, men du må ihvertfall legge til RefCount(const T& new_value); i headern siden du prøver å definere den. du definerer også funksjonene feil template<class T> RefCount<T>::RefCount& clone() const skal være template<class T> RefCount<T>& RefCount<T>::clone() const Endret 31. desember 2004 av saboi Lenke til kommentar
søppel Skrevet 31. desember 2004 Del Skrevet 31. desember 2004 #include <iostream> #include <cstdlib> #include <cstdio> using namespace std; template<class T> class RefCount { public: //Consturctors RefCount(); RefCount(const T* new_value); RefCount(const RefCount& new_value); //Destructor ~RefCount(); //General interface RefCount& make_unique() const; RefCount& clone() const; T& operator->(); private: T* p; std::size_t* refptr; }; // RefCount //Constructors, destructors template<class T> RefCount<T>::RefCount() :p(T()), refptr(std::size_t(1)) { } template<class T> RefCount<T>::RefCount(const T* new_value) { if(!&new_value == p) { if(!*refptr--) delete p; *refptr--; this = &new_value; } } template<class T> RefCount<T>::RefCount(const RefCount& new_value) { if(!&new_value == this) { if(!this->refptr) { this.refptr = &new_value->refptr++; this.p = &new_value.p; } } } template<class T> RefCount<T>::~RefCount() { if(!*(--refptr)) { delete refptr; delete p; p = 0; } else { delete p; p = 0; } } //General interface template<class T> RefCount<T>& RefCount<T>::make_unique() const { return new T(p); } template<class T> RefCount<T>& RefCount<T>::clone() const { return new RefCount(*this); } template<class T> T& RefCount<T>::operator->() { return p; } // Av en eller annen grunn (som jeg ikke kommer på just nuh) går det ikke å bruke operator= slik i C++ .. /* //Non-members... template<class T> T& operator=(T& lhs, const RefCount<T>& rhs) { //lhs = rhs->p; //return lhs; } */ /* template<class T> RefCount<T>& operator=(RefCount<T>& lhs, const RefCount<T>& rhs) { if(!&lhs == &rhs) { if(lhs->p != rhs->p) lhs.~RefCount(); else { &lhs = &rhs; lhs->refptr++; } } return(lhs); } */ /* template<class T> T& operator=(RefCount<T>& lhs, T& rhs) { lhs = RefCount<T>(rhs); return lhs; } */ int main() { return(0); } // main Jeg har kun rettet på syntax-feil, hva som skjer (semantikken), har jeg ikke tittet på. Lenke til kommentar
Dead_Rabbit Skrevet 31. desember 2004 Forfatter Del Skrevet 31. desember 2004 Takk for hjelpa! Funker nå! Bare litt kipt det med operator=() Lenke til kommentar
saboi Skrevet 31. desember 2004 Del Skrevet 31. desember 2004 operator= må være en funksjon av klassen. den kan ikke være en funksjon alene Lenke til kommentar
søppel Skrevet 1. januar 2005 Del Skrevet 1. januar 2005 Snedig at det er sånn .. hvorfor? Irriterer meg at det blir satt grenser - selv om noe kanskje er idiotisk. Lenke til kommentar
Dead_Rabbit Skrevet 1. januar 2005 Forfatter Del Skrevet 1. januar 2005 Enig der. Lenke til kommentar
saboi Skrevet 1. januar 2005 Del Skrevet 1. januar 2005 (endret) Snedig at det er sånn .. hvorfor? Irriterer meg at det blir satt grenser - selv om noe kanskje er idiotisk. det blir vel ikke satt noe fler grenser for = enn for de andre operatorene. operatorene kan jo bare overlastes med et bestemt antall parametere. det gir f.eks ikke mye mening å overlaste operator+(klasse a, klasse b, klasse c) siden d = a + b c; er rart. derfor tar operator= bare et argument og må derfor være medlem av klassen siden du ikke kan vite den andre typen hvis den ikke er medlem av klassen. klart man kunne finne på å si at operator= skulle ha 2 parametere, men når man overlaster = vil man gjerne at operator= skal ha tilgang til alle medlemmene så den kan kopiere private medlemmer osv. da slipper man å skrive friend klasse operator=(const klasse& lhs, const klasse& rhs); osv for hver operator= man overlaster. en annen ting er at en klasse får en default operator= hvis du ikke overlaster den selv og da ville det blitt vanskelig å velge mellom default eller en funksjon som ikke er medlem av klassen. ble sikkert veldig klønete forklart siden jeg er fantastisk dårlig til å ordlegge meg, men dette sier standarden (ihvertfall 96-standarden eller noe, den som er tilgjengelig på nett siden jeg ikke har den nyeste, men akkurat operator= har vel neppe blitt endret så mye): 13.5.3 Assignment [over.ass] 1 An assignment operator shall be implemented by a non-static member function with exactly one parameter. Because a copy assignment opera- tor operator= is implicitly declared for a class if not declared by the user (_class.copy_), a base class assignment operator is always hidden by the copy assignment operator of the derived class. Endret 1. januar 2005 av saboi Lenke til kommentar
Dead_Rabbit Skrevet 1. januar 2005 Forfatter Del Skrevet 1. januar 2005 (endret) Nå er koden oppdatert! Men jeg har fortsatt problemer når jeg skal bruke klassen i et program... Edit: Kansje det er mulig å gjør noe sånt som dette: template<class T> T& T::operator=(RefCount&); isteden for: template<class T> T& operator=(T&, RefCount&); som ikke er lovlig... Endret 1. januar 2005 av zirener Lenke til kommentar
saboi Skrevet 1. januar 2005 Del Skrevet 1. januar 2005 nei, det går ikke an. det ville vært utrolig teit hvis du tenker på det koden kompilerer her Lenke til kommentar
Dead_Rabbit Skrevet 1. januar 2005 Forfatter Del Skrevet 1. januar 2005 Koden kompilerer her også... Men når jeg initialiserer objektene på forskjellige måter som jeg har vist i den oppdaterte koden, så funker det ikke. Noen som kan hjelpe? Lenke til kommentar
A_N_K Skrevet 2. januar 2005 Del Skrevet 2. januar 2005 Du har jo ikke definert operator= for T, kun for T&? Lenke til kommentar
søppel Skrevet 2. januar 2005 Del Skrevet 2. januar 2005 (endret) derfor tar operator= bare et argument og må derfor være medlem av klassen siden du ikke kan vite den andre typen hvis den ikke er medlem av klassen. Her er det ingen tvil hvilke typer det er snakk om: typename<T> T& operator=(T& a, RefCount<T>& b); RefCount<int> ri; int i; i = ri; Til og med dette burde vært lovelig: template<typename T1, typename T2> operator=(T1& o1, T2& o2); Jeg vil ha friheten til å gjøre, kanskje, idiotiske og gale ting. = burde være en ting man kan spesifisere for "hva som helst": * fra en egendefinert type til en innebyggd type * fra en egendefinert type til en egendefinert type * ...baaah... ..I grunn burde det ikke vært noen forskjell her mellom egendefinerte og innebyggde typer. Det er rart - men des mer man generaliserer og forenkler noe (noe som ofte kan være vanskelig), dess mindre blir språket og syntaxen; men mulighetene og kraften til å uttrykke seg øker proposjonalt. Så et språk som går 1-1 fra hode (problem space) til kode hadde vært fint, og hvis det siden - når man var ferdig, gikk å legge til detaljer som gjorde at koden matchet maskinens verden (solution space), hadde det vært fint. Tenker på å legge til ting (deklarasjoner o.l. f.eks.) som gjorde at det ble lettere for kompileren å lage rask maskinkode (mindre tid og rom) - dette går i flere språk. C++ har mange fordeler - men det er mye som ikke er godt gjennomtenkt og er unødvendig komplisert .. IMHO. Det kan hende noe av grunnen her er bakoverkompatibilitet med C, jeg har ikke tenkt så nøye på det. Edit: Jeg snakker altså ikke om C++ og standaren, jeg snakker om idéer rundt språket - og språk generellt egentlig. Endret 2. januar 2005 av søppel Lenke til kommentar
Dead_Rabbit Skrevet 2. januar 2005 Forfatter Del Skrevet 2. januar 2005 A N K: Er det ikke sånn at man gjør: void f(int&); så man slepper å kalle funksjonen med f(&a); ? Lenke til kommentar
A_N_K Skrevet 2. januar 2005 Del Skrevet 2. januar 2005 I deklarasjonen av RefCount har du T& operator=(T); men det finnes ingen tilsvarende definisjon, kun for T&. g++ prøver i dette tilfellet å instansiere med T = int, ikke T = int&. Lenke til kommentar
Klette Skrevet 2. januar 2005 Del Skrevet 2. januar 2005 Søppel: *host*lisp propaganda*host* Lenke til kommentar
søppel Skrevet 2. januar 2005 Del Skrevet 2. januar 2005 (endret) Sannt - men si i fra om du finner noe bedre da! (så driver jeg propaganda for det i stedet) Lisp er det språket det lånes mest idéer av i det siste har jeg intrykk av. Se f.eks. på Boost. Edit: "Bedre" er, igjen, et relativt ord. Som nevnt i tidligere tråder ( http://forum.hardware.no/index.php?showtop...dpost&p=3391621 ) så har C og C++ sin plass. Endret 2. januar 2005 av søppel Lenke til kommentar
saboi Skrevet 2. januar 2005 Del Skrevet 2. januar 2005 Her er det ingen tvil hvilke typer det er snakk om: typename<T> T& operator=(T& a, RefCount<T>& b); RefCount<int> ri; int i; i = ri; Til og med dette burde vært lovelig: template<typename T1, typename T2> operator=(T1& o1, T2& o2); Jeg vil ha friheten til å gjøre, kanskje, idiotiske og gale ting. = burde være en ting man kan spesifisere for "hva som helst": som jeg sa, hvordan skal compilern vite hvem den skal velge av en default operator= for T som blir laget automatisk, en som forfattern kanskje har skrevet selv for T eller din funksjon? og den andre funksjonen din er jo helt idiotisk, skal du lage en universell operator= som tar hvilken som helst to typer da? hvordan i helvete har du tenkt til å implementere den, selv om det var lovlig? det går ikke.. det er nok kanskje mer gjennomtenkt enn det du har tenkt på det virker det som. fordi begge de der to er ganske åpenlyse at det ville vært umulig å implementere Lenke til kommentar
søppel Skrevet 2. januar 2005 Del Skrevet 2. januar 2005 (endret) en default operator= for T som blir laget automatisk, en som forfattern kanskje har skrevet selv for T eller din funksjon? Det burde kun eksistere én =, og den burde kunne overlastes manuellt av brukeren i forskjellige grader av generalitet. Jeg vil ikke tenke på, eller spesifisere (selv ja) slike detaljer før høyst nødvendig. #include <iostream> using namespace std; template<typename T> class RefCount { public: T& getIt() { return(_o); } // getIt private: T _o; }; // RefCount // Dette er operator=, bare i en annen form (som gjør dette mulig i C++). template<typename T> T& assign(T& a, RefCount<T>& b) { return(a = b.getIt()); // = skulle ledet tilbake til mindre og mindre generelle funksjoner - til man havnet "på bunn" } // assign int main(int argc, char** argv) { RefCount<int> ri; ri.getIt() = 123; int i; assign(i, ri); cout << i << endl; return(0); } // main Jeg vet det andre eksempelet er idiotisk - det understreker poenget mitt; det burde vært lovelig sett i sammenheng med syntax. Edit: For .. det finnes flere grader av idioti - noen ganger er det hensiktsmessig i ekstreme tilfeller. Endret 2. januar 2005 av søppel Lenke til kommentar
saboi Skrevet 2. januar 2005 Del Skrevet 2. januar 2005 joda, men når du først har fått det for deg at det burde gå an, er det ikke da høyst nødvendig å forklare hvordan det skal gå an? jeg ser heller ikke det på som en svakhet at den andre ikke går an bare fordi det er syntaktisk korrekt, heller en styrke i språket. og igjen, hvis kompilatoren lot det være lovlig syntaks, så ville den fortsatt ikke vite hvordan den skulle generere koden og derfor må den si nei til det. jeg ser poenget ditt, men jeg tror fortsatt at sånn som det er nå er den eneste løsningen. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå