Steinbitglis Skrevet 8. januar 2005 Del Skrevet 8. januar 2005 (endret) jeg prøver å lage min egen lille manipulator. Se for deg cout << bin << 127; med resultatet: 01111111 Problemet er at jeg må lage en klasse som har et ostream objekt som medlem. Kompilatoren klager på at det ikke er konstruktør eller at jeg ikke har skrevet noe i konstruktøren. (får ikke initialisert ostreamobjektet) Klassen inneholder kunn dette medlemmet og noen funksjoner. namespace bmanip{ using std::ostream; using std::stringstream; using std::INT_MAX; class binary_manipulator{ public: binary_manipulator():binaryobject() { } ostream& operator<< (ostream& o) { stringstream bufferstrom; bufferstrom << o; int i = 0; bufferstrom >> i; if(!i)return o; for (int p = INT_MAX;p>0;p/=2) { if (p & i) binaryobject << 1; else binaryobject << 0; } return binaryobject; } private: ostream binaryobject; }; binary_manipulator bin; } Endret emnetittel. Tre-ords-regelen er her for en grunn. PoleCat Endret 9. januar 2005 av PoleCat Lenke til kommentar
Peter Skrevet 9. januar 2005 Del Skrevet 9. januar 2005 Trodde man skulle unngå å lage iostream operatorerer som medlemmeri klasser? Definer den i public scope, med reference til binary_mainpulator som et av argumentene. Deretter legger du til friend ostream& operator<<ostream&(ostream&, binary_manipulator&); i binary_mainpulator klassen (Dette er litt gjetting, men tror det er en bedre løsning) Lenke til kommentar
Steinbitglis Skrevet 9. januar 2005 Forfatter Del Skrevet 9. januar 2005 Har funnet ut mye av det der ja.... Slik jeg ser det, er løsningen min umulig fordi <<operatoren er venstre-assosiativ (vanskelig ord). Fikk til det jeg ville, med en liten endring: cout << (bin << 127); Dette fungerer. Ostream&-operatoren satt jeg opp slik du skrev. I tillegg la jeg inn friend binary__manipulator& operator<< (binary__manipulator&, int&); Dessuten er medlemet ikke lenger en ostream, men en stringstream. Etter mye trøbling fant jeg og ut at for å lese av en stringstream, må man bruke stringstream::str(); header-filen som inneholder bin, ser nå slik ut #ifndef _BIN_MANIP#define _BIN_MANIP #ifndef _CPP_SSTREAM #include <sstream> #endif #ifndef _CPP_OSTREAM #include <ostream> #endif #ifndef _CPP_CLIMITS #include <climits> #endif namespace bmanip{ using std::stringstream; using std::ostream; class binary__manipulator{ friend ostream& operator<< (ostream&, binary__manipulator&); friend binary__manipulator& operator<< (binary__manipulator&, int&); private: stringstream binaryobject; }; binary__manipulator bin; ostream& operator<< (ostream& ut, binary__manipulator& b) { int i = 0; b.binaryobject >> i; if(!i)return ut; stringstream super; for (int p = (INT_MAX/2)+1;p>0;p/=2) { if (p & i) super << 1; else super << 0; } ut << "Binaert: " << super.str(); return ut; } binary__manipulator& operator<< (binary__manipulator& b, int& i) { b.binaryobject << i; return b; } } #endif Begynner å likne på en biblioteks-stil synes jeg. Jeg er ganske fornøyd med oppsettet. Har liksom aldri brydd meg om å skrive ryddig før. BTW, ser jeg selv at de include-makroene er litt vel overdrevne. Noen forslag til forbedring av filen? Hvis jeg skal lage mine egne header-filer, som jeg kan bruke seinere, hva må forbedres? Lenke til kommentar
søppel Skrevet 10. januar 2005 Del Skrevet 10. januar 2005 (endret) Jeg har ikke fulgt med her, men hva med inlining? Dette er rimelig små kodesnutter, og det kan dermed hende dette er aktuellt. Er ikke sikker på hvor bra koden er, minns jeg ryddet en del opp i den etter posten ble lagt ut, men du skjønner sikkert poenget eller idéen den prøver å få frem: http://forum.hardware.no/index.php?showtop...dpost&p=2233527 (selvfølgelig ikke nødvendig, du kan jo i grunn bare bruke "vanlig" inline) Edit2: Du trenger ikke include-guardsene du har rundt forbi. Endret 10. januar 2005 av søppel Lenke til kommentar
Steinbitglis Skrevet 14. januar 2005 Forfatter Del Skrevet 14. januar 2005 (endret) Ser ikke helt viktigheten med å gjøre funksjonene inline. Ettersom det er en bibliotekfil, vet man jo aldri hvor mange ganger funksjonene skal tas i bruk. For et lite program gir det kanskje en litt bedre ytelse, men jeg prøver å lage en fil til allslags bruk. Rett på meg hvis jeg tar feil. Har nå oppgradert det hele litt Følgende vil nå fungere fint. cout << "Tallet" << tall << " er " << bin << tall << " binaert"; Operatoren: binary_manipulator& operator<<(ostream&, binary_manipulator&) lagrer en adresse til en ostream (eksempelvis cout) i objektet og returnerer en referanse til objektet. Dermed har nå objektet ansvaret for alt som kommer inn. Denne gangen la jeg bin i det globale navnerommet, siden den er det eneste viktige i filen. (cout << bin) //lagrer &cout og returnerer adressa til bin (bin << int) //bin lager binærtallet og sender det til cout (bin << char*) //sender strengen videre til cout //----------------bin:manip.h----------------- #ifndef _BIN_MANIP #define _BIN_MANIP #include <sstream> #include <ostream> #include <climits> namespace bmanip{ using std::stringstream; using std::ostream; class binary__manipulator{ friend binary__manipulator& operator<< (ostream&, binary__manipulator&); friend binary__manipulator& operator<< (binary__manipulator&, int&); friend binary__manipulator& operator<< (binary__manipulator&, char*); private: stringstream binaryobject; ostream* cout_referanse; }; inline binary__manipulator& operator<< (ostream& ut, binary__manipulator& b) { b.cout_referanse = &ut; return b; } binary__manipulator& operator<< (binary__manipulator& b, int& i) { if(!i)return b; stringstream super; for (int p = (INT_MAX/2)+1;p>0;p/=2) { if (p & i) super << 1; else super << 0; } *b.cout_referanse << super.str(); return b; } inline binary__manipulator& operator<< (binary__manipulator& b, char* i) { *b.cout_referanse << i; return b; } } bmanip::binary__manipulator bin; #endif Endret 14. januar 2005 av Styggentorsken Lenke til kommentar
søppel Skrevet 14. januar 2005 Del Skrevet 14. januar 2005 (endret) ..vet man jo aldri hvor mange ganger funksjonene skal tas i bruk. Riktig det, men er funksjonene små nok tar koden for kallet like mye (eller neeesten) plass som selve funksjons-koden. U c? Da blir det hipp som happ sånn rom-messig sett, men forskjellen i tid kan variere sterkt siden et kall tar mer tid. Det blir en vurderingssak; opp til deg. (Edit: bruk en disassembler og/eller kjør noen benchmarks -- det er uansett optimaliseringer, så er kanskje ikke så viktig før tilslutt) Kan ta en titt på resten litt ut over dagen .. må få ordna meg noe middag her nå ... :] (Edit3: Tror jeg droppa det, C++ er for mye rot for meg i dag) Edit2: Det A_N_K sier under stemmer, men om du gir den noen hint (-O2 eller -O3 ..o.l.) at du virkelig vil optimalisere så er det større sjans for at inline blir overholdt. Dette er det klienten av biblioteket (headeren) som (av)gjør. Endret 14. januar 2005 av søppel Lenke til kommentar
A_N_K Skrevet 14. januar 2005 Del Skrevet 14. januar 2005 Kompilatoren er ikke tvunget til å respektere inline, den bruker som regel en heuristikk for å bestemme om en funksjon skal inlines. Lenke til kommentar
søppel Skrevet 14. januar 2005 Del Skrevet 14. januar 2005 (endret) Ohh .. btw. - det kan hende jeg er full her, men det å definere et instans av klassen i headeren: ...bmanip::binary__manipulator bin; ... ..er ingen god idé da flere .cpp-filer kan inkludere headeren; linker-feil! uhm. . mye mulig at jeg surrer her Edit: For å være helt ærlig ville jeg droppa hele greia og gjordt det veldig enkelt og idiot-sikkert: #include <iostream> #include <sstream> #include <climits> inline std::string bin(int i) { std::stringstream ss; for(int p = (INT_MAX / 2) + 1; p > 0; p /= 2) { if (p & i) ss << 1; else ss << 0; } return(ss.str()); } // bin using namespace std; int main() { for(unsigned int i = 0; i < 50; i++) cout << bin(i) << endl; return(0); } // main Det kan hende det er fordi jeg ikke finner noen god nok løsning som fungerer i alle situasjoner, da jeg ikke er nok kjennt med det interne opplegget i io-biblioteket. Endret 14. januar 2005 av søppel Lenke til kommentar
Steinbitglis Skrevet 14. januar 2005 Forfatter Del Skrevet 14. januar 2005 (endret) tja, tenkte kanskje det kunne være lærerikt , men da jeg fikk til klassen såpass bra, kan det hende at jeg bruker den littegrann. Gjør ikke include-guardsene at filen ikke inkluderes flere ganger?? har sliti mye med io-biblioteket ja, tror nok det finnes bedre løsninger enn denne, men jeg klarer i alle fall å tilfredsstille alle forventningene jeg hadde til klassen når jeg begynnte på den. Hva mangler eventuelt? Jeg tror klassen holder til alt jeg skal bruke den til. BTW, løsningen din er også helt grei. Jeg ville nok brukt den hvis jeg bare måtte lage noe i farta eller hvis ytelse hadde noe å si. Endret 14. januar 2005 av Styggentorsken Lenke til kommentar
søppel Skrevet 14. januar 2005 Del Skrevet 14. januar 2005 (endret) Gjør ikke include-guardsene at filen ikke inkluderes flere ganger?? Jo, men bare pr. kompilering. Når man kompilerer flere filer så inkluderes headeren flere ganger, og du får flere definisjoner av symbolet 'bin'. a.cpp: #include "bin.hpp" int main() { return(0); } b.cpp: #include "bin.hpp" bin.hpp: #ifndef _BIN_ #define _BIN_ class Bin { }; // Bin Bin bin; #endif // #ifndef _BIN_ g++ a.cpp b.cpp -o prog/tmp/ccySSKsA.o(.bss+0x0): multiple definition of `bin' /tmp/ccUVWaTI.o(.bss+0x0): first defined here collect2: ld returned 1 exit status Definisjonen av symbolet 'bin' må legges i en egen .cpp-fil (bibliotek). Endret 14. januar 2005 av søppel Lenke til kommentar
Steinbitglis Skrevet 18. januar 2005 Forfatter Del Skrevet 18. januar 2005 //--------bin_manip.h--------- #ifndef _BIN_MANIP #define _BIN_MANIP #include bin_manip.cpp /*....*/ namespace bin_manip{ /*....................*/ class binary_manipulator{ /*...*/ }; }; #endif //--------bin_manip.cpp--------- #include bin_manip.h class bin_manip::binary_manipulator; bin_manip::binary_manipulator bin; Vil dette fungere? 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å