Google, Het mirakel van de 21e eeuw!!!!
Siditamentis astuentis pactum.
edit: veiliger is: snprintf
Those who do not understand Unix are condemned to reinvent it, poorly.
Maar, (ik heb ook maar een beperkte kennis c++), kun je het niet zo oplossen:
1
| (char)iGetal; |
I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.
Daarmee zet je het getal "100" om in een ascii char met ascii waarde 100 , dat wil hij nou net niet.Op donderdag 25 juli 2002 22:15 schreef -Avalanche- het volgende:
De functie itoa bestaat ook dacht ik zo
Maar, (ik heb ook maar een beperkte kennis c++), kun je het niet zo oplossen:
code:
1 (char)iGetal;
Those who do not understand Unix are condemned to reinvent it, poorly.
Dat is dus de verkeerde kant op.Op donderdag 25 juli 2002 22:15 schreef Aaargh! het volgende:
sprintf
edit: veiliger is: snprintf
Van char "100" naar int 100.
Google, Het mirakel van de 21e eeuw!!!!
char *_itoa( int value, char *string, int radix );
Dat is wat je zoekt
i5-12600K PRIME Z690M-PLUS D4 64GB 980 Pro M.2 1TB MBA M1 13" 8GB 256GB (Late '20)
Verwijderd
Op donderdag 25 juli 2002 22:13 schreef active2 het volgende:
De int waarde 100 naar de char waarde "100"
Wat wil je nouOp donderdag 25 juli 2002 22:27 schreef active2 het volgende:
Van char "100" naar int 100.
In welke header file staat die dan?Op donderdag 25 juli 2002 22:31 schreef ghostrdr01 het volgende:
Zoals al eerder aangehaald:
char *_itoa( int value, char *string, int radix );
Dat is wat je zoekt
Google, Het mirakel van de 21e eeuw!!!!
Anywayz Help, index en dan _itoa en dan vertelt je IDE-help wel in welke header hij staat en anders doe je ff een find in files op de include directory van je IDE.
i5-12600K PRIME Z690M-PLUS D4 64GB 980 Pro M.2 1TB MBA M1 13" 8GB 256GB (Late '20)
[os=linux] en compiler is g++Op donderdag 25 juli 2002 22:36 schreef ghostrdr01 het volgende:
Ja eh moet ik hier dan serieus antwoord op geven ? Mag toch aannemen dat je weet hoe je help werkt
Anywayz Help, index en dan _itoa en dan vertelt je IDE-help wel in welke header hij staat en anders doe je ff een find in files op de include directory van je IDE.
Google, Het mirakel van de 21e eeuw!!!!
Verwijderd
char theBuffer[4];
sprintf( theBuffer, "%d", 100 );
of
char theBuffer[4];
itoa( 100, theBuffer, 10 ); /* 10 is je basis (10-delig talstelsel hier) */
in C++ kun je ook gebruik maken van "output string streams" :
#include <sstream>
using namespace std;
...
ostringstream theStringStream;
theStringStream << 100;
// vanaf hier kan je mbv theStringStream.str() een string opvragen waarmee je whatever kan doen ...
cout << "Je getal als een string : " << theStringStream.str() << endl;
Er zullen nog wel manieren zijn...
Desnoods doe je zelf ff snel de conversie enzo, bvb door steeds de rest na deling van 10 te nemen en al die digits in een char te gieten en aan elkaar te plakken... maar inderdaad, waarom het wiel opnieuw uitvinden ?
[edit]
sorry : itoa staat in stdlib.h en sprintf staat in stdio.h maar ik ging er ff van uit dat je dat wel zou weten
Hij wil de integer waarde in een stringetje zodat je hem bv in een grote string kan douwen, zoiets van ik ben 5 jaarOp donderdag 25 juli 2002 22:31 schreef Sneechy het volgende:
[..]
[..]
Wat wil je nou.
waarbij je dus kan doen strcpy(var,"ik ben "); strcat(var, leeftijd); strcat(var, " jaar"); oid
i5-12600K PRIME Z690M-PLUS D4 64GB 980 Pro M.2 1TB MBA M1 13" 8GB 256GB (Late '20)
Wat wil je nut, van een int naar een char* of van een char naar een int. aangezien je zelf al met atoi kwam (char to int) nam ik aan dat je snprintf wilde (int to char)Op donderdag 25 juli 2002 22:27 schreef active2 het volgende:
[..]
Dat is dus de verkeerde kant op.
Van char "100" naar int 100.
Those who do not understand Unix are condemned to reinvent it, poorly.
Dit kan idd ook prima of je doetOp donderdag 25 juli 2002 22:38 schreef _piranha_ het volgende:
in C (maar dat kan een C++ compiler ook wel) :
char theBuffer[4];
sprintf( theBuffer, "%d", 100 );
of
char theBuffer[4];
itoa( 100, theBuffer, 10 ); /* 10 is je basis (10-delig talstelsel hier) */
in C++ kun je ook gebruik maken van "output string streams" :
#include <sstream>
using namespace std;
...
ostringstream theStringStream;
theStringStream << 100;
// vanaf hier kan je mbv theStringStream.str() een string opvragen waarmee je whatever kan doen ...
cout << "Je getal als een string : " << theStringStream.str() << endl;
Er zullen nog wel manieren zijn...
Desnoods doe je zelf ff snel de conversie enzo, bvb door steeds de rest na deling van 10 te nemen en al die digits in een char te gieten en aan elkaar te plakken... maar inderdaad, waarom het wiel opnieuw uitvinden ?
strstream str;
int leeftijd = 5;
char message[100];
str << "Ik ben " << leeftijd << " jaar";
str >> message;
cout << message << endl;
i5-12600K PRIME Z690M-PLUS D4 64GB 980 Pro M.2 1TB MBA M1 13" 8GB 256GB (Late '20)
Verwijderd
Inderdaad, mogelijkheden zat gewoon !Op donderdag 25 juli 2002 22:41 schreef ghostrdr01 het volgende:
Dit kan idd ook prima of je doet
strstream str;
int leeftijd = 5;
char message[100];
str << "Ik ben " << leeftijd << " jaar";
str >> message;
cout << message << endl;
denk denk denk denkOp donderdag 25 juli 2002 22:39 schreef Aaargh! het volgende:
[..]
Wat wil je nut, van een int naar een char* of van een char naar een int. aangezien je zelf al met atoi kwam (char to int) nam ik aan dat je snprintf wilde (int to char)
atoi --> char naar int
Die snprintf is een leuke functie nu even opzoeken hoe dat ding precies werkt. Waar kan ik vinden hoe dat precies werkt? Uit die header file word je niet veel wijs.
Google, Het mirakel van de 21e eeuw!!!!
man snprintfOp donderdag 25 juli 2002 22:45 schreef active2 het volgende:
Die snprintf is een leuke functie nu even opzoeken hoe dat ding precies werkt. Waar kan ik vinden hoe dat precies werkt? Uit die header file word je niet veel wijs.
Those who do not understand Unix are condemned to reinvent it, poorly.
De _ aan het begin is een redelijke hint dat het een MS-only extensie is. snprintf() in C, of std::ostringstream in C++ zijn de standaard methoden, boost::lexical_cast<std::string> werkt ookOp donderdag 25 juli 2002 22:31 schreef ghostrdr01 het volgende:
Zoals al eerder aangehaald:
char *_itoa( int value, char *string, int radix );
Dat is wat je zoekt
En verder wil je in C++ std::string gebruiken ipv char*
Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein
1
2
3
4
5
6
7
8
| #include <sstream>
template <class T>
std::string toString(const T& i) {
std::ostringstream sstr;
sstr << i;
return sstr.str();
} |
ik gebruik daarvoor altijd itoa
int i = 5; //integer die je wilt converteren
char s // hier wil je 'm ingooien
itoa(i, &s, 10); //10 betekend decimaal stelsel
Naar de bioscoop? => gebruik de app op Byoscoop.nl
Vervolgens was het probleem dat de topicstarter niet wist in welke headerfiles ie et kon vinden (ff zoeken had dat opgelost maar ok
p0m p0m
Naar de bioscoop? => gebruik de app op Byoscoop.nl
Het probleem is dat jullie de borland IDE gebruiken enzo.. Maar ik programmeer in linux met g++ en dan heb je toch andere functies maar goed in elk geval bedankt ik ben enorm geholpen.Op vrijdag 26 juli 2002 10:45 schreef Boy het volgende:
je wilt toch niet zeggen dat hier zo een lange thread over ontstaat??
ik gebruik daarvoor altijd itoa
int i = 5; //integer die je wilt converteren
char s // hier wil je 'm ingooien
itoa(i, &s, 10); //10 betekend decimaal stelsel
Google, Het mirakel van de 21e eeuw!!!!
En blijkbaar kwam er nog steeds niet iemand met de string stream gebruikende template functie aan. Wat toch echt wel de C++ standaard is voor dit (probleem)Op vrijdag 26 juli 2002 10:45 schreef Boy het volgende:
je wilt toch niet zeggen dat hier zo een lange thread over ontstaat??
Crash, burn, get fired.Op vrijdag 26 juli 2002 10:45 schreef Boy het volgende:
je wilt toch niet zeggen dat hier zo een lange thread over ontstaat??
ik gebruik daarvoor altijd itoa
int i = 5; //integer die je wilt converteren
char s // hier wil je 'm ingooien
itoa(i, &s, 10); //10 betekend decimaal stelsel
itoa schrijft naar een array van chars; s is een "array" met lengte 1. Daar kun je dus net een \0 in krijgen, maar "100" is 4 karakters. Weg stack. snprintf had't ondekt, std::stringstream heeft het probleem niet.
Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein
Verwijderd
En voor de 7/8 bitters onder ons die alleen ascii willen, is er altijd sprintf, wel de juiste grootte in je buffertje alloceren
Voor de allergrootste bitnaaiers is er natuurlijk de eigengeschreven routine die een getal omzet van talstelsel A naar talstelsel B, die kan worden omgebakken naar een waarde in talstelsel A naar een ascii representatie ervan.
Dat is geen goed OO design. Een string is geen formatter.Op vrijdag 26 juli 2002 12:58 schreef Otis het volgende:
Mja, elk zelfrespecterende string class heeft een 'Format' achtige method, en anders kies je voor een string class die er een heeft.
Als je nou zegt dat elke zelfrespecterende string class een bijpassende formatter class heeft, dan geef ik je helemaal gelijk.
De reden hiervoor is dat formatting rekening moet houden met een a priori onbekend aantal UDTs. Kijk maar naar de std:: aanpak. Als je al die formatting data permanent wil meeslepen met elke string, in plaats van alleen voor die strings die je format en alleen gedurende het formatten, dan wordt de overhead van je string class aanmerkelijk groter.
Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein
Ok, uitdaging: Gegeven INT_MAX en consorten, hoeveel chars heb je nodig zodat je een int zeker kunt printen?Op vrijdag 26 juli 2002 12:58 schreef Otis het volgende:
En voor de 7/8 bitters onder ons die alleen ascii willen, is er altijd sprintf, wel de juiste grootte in je buffertje alloceren
Oftewel, wat is xxx in termen van INT_MAX e.d. in
1
2
3
4
5
| void foo( int i )
{
char buf[ xxx ];
sprintf( &x, "%d", i );
} |
't moet het natuurlijk wel op m'n 64 bit doos doen, maar op m'n DOS doos geen overbodige chars gebruiken.
Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein
Verwijderd
1
2
3
4
5
6
7
| #define xxx (((int)log10(INT_MAX)) + 3) /* + 1 om logaritme op te plussen naar integere macht van 10 * + 1 voor het evt. minteken * + 1 voor terminating '\0' * --- = * + 3 */ |
Overigens is je foo() erg brak
Als je String class zelf formatting doet, wordt het heel lastig om (een vorm van) Locales te gebruiken. Het is erg interessant om de C++ stream classes is helemaal door te gaan, en uit te zoeken op welk punt er nou uiteindelijk een character wordt geschreven. Petje af voor degene die dit ontworpen hebben hoor!Op vrijdag 26 juli 2002 12:58 schreef Otis het volgende:
Mja, elk zelfrespecterende string class heeft een 'Format' achtige method, en anders kies je voor een string class die er een heeft.
En voor de 7/8 bitters onder ons die alleen ascii willen, is er altijd sprintf, wel de juiste grootte in je buffertje alloceren
Als je alleen ascii wilt kan je gewoon std::basic_ostringstream<char> gebruiken. Anders wchar. (char is per definitie 1 byte, dit hoeven echter geen 8 bits te zijn
Verwijderd
C++, multiple inheritance, etc. Waarom zou een String class geen format method mogen hebben? Het is toch een method die werkt op de data IN de class, hetgeen juist is waar OO voor is bedoeld! Door multiple inheritance kun je je formatter class functionaliteit inbakken in je string class, maar dat hoeft natuurlijk niet. Een string class kan perfect een printf achtige format method hebben, iedere stringclass heeft toch ook een search functie? Of wil je dat ook als 'non-OO' afdoen want het is geen full blown regexp class?Op vrijdag 26 juli 2002 13:18 schreef MSalters het volgende:
[..]
Dat is geen goed OO design. Een string is geen formatter.
Als je nou zegt dat elke zelfrespecterende string class een bijpassende formatter class heeft, dan geef ik je helemaal gelijk.
Ja natuurlijk wordt de overhead groter. Je zou de string class die de format methods hebben als een is-a class derivative kunnen zien van de normale stringclass, maar no offence, wat heb je aan een stringclass zonder handige methods op de stringdata IN de class? (Als developer) geen moer, want je kunt dan net zo goed zelf met multibyte arrays gaan lopen rommelen, wat helaas ook veel developers denken te moeten doen.De reden hiervoor is dat formatting rekening moet houden met een a priori onbekend aantal UDTs. Kijk maar naar de std:: aanpak. Als je al die formatting data permanent wil meeslepen met elke string, in plaats van alleen voor die strings die je format en alleen gedurende het formatten, dan wordt de overhead van je string class aanmerkelijk groter.
Dit is een hele goeie oplossing maar nu zit ik met het volgende probleem:Op vrijdag 26 juli 2002 10:37 schreef Zoijar het volgende:
Algemene oplossing:
code:
1 2 3 4 5 6 7 8#include <sstream> template <class T> std::string toString(const T& i) { std::ostringstream sstr; sstr << i; return sstr.str(); }
strcpy(waarde, toString(100));
Werkt niet.
error:
testje2.cpp: In function `int main(...)':
testje2.cpp:14: cannot convert `basic_string<char,string_char_traits<char>,__default_alloc_template<true,0> >()' from type `basic_string<char,string_char_traits<char>,__default_alloc_template<true,0> >' to type `const char *'
Het heeft wat met die pointers te maken maar ik weet niet hoe ik dit kan oplossen omdat ik nog nooit met die templates gewerkt heb.
[/me] is overigens druk aan het lezen
Google, Het mirakel van de 21e eeuw!!!!
Verwijderd
Mja, het zal allemaal best knap zijn, maar of het allemaal nodig is in de meeste gevallen betwijfel ik. String processing is HET grote manko van C en C++ achtige talen, bij gebrek aan native stringtypes, waardoor je snel geneigd bent te gaan kijken naar classes die dat dan voor je oplossen. Locales zijn imho juist voor de interpretatie van de multibyte (unicoded) stringdata, dus of je dat soort logica in je stringclass wilt, is natuurlijk vers 2.Op vrijdag 26 juli 2002 13:56 schreef Zoijar het volgende:
[..]
Als je String class zelf formatting doet, wordt het heel lastig om (een vorm van) Locales te gebruiken. Het is erg interessant om de C++ stream classes is helemaal door te gaan, en uit te zoeken op welk punt er nou uiteindelijk een character wordt geschreven. Petje af voor degene die dit ontworpen hebben hoor!
Ik zal wel als een domme boer klinken maar ik kan me niet aan de indruk onttrekken dat de functionaliteit zoals die wordt geleverd door bv CString (heb ik het even niet over de interne crappyness van die class
Veel mensen neigen ernaar om de meest algemene oplossing als de 'beste' te betitelen, maar algemenisering komt altijd met een prijs, evenals verregaande specialisatie. Als je ziet wat voor gemak een string type in C# oplevert, wil je die functionaliteit gewoon in C++, hoe dat verder geregeld wordt zal de developer worst zijn. Of dat door een serie templates wordt geregeld of door 3 inheritance bomen, is dat nou belangrijk? Het gaat erom dat de developer een stringclass tot zn beschikking heeft die de Basic (pun intended) handelingen op een string uit kan voeren zonder morren. Dat je uiteraard wilt dat unicode support standaard is, is logisch.
waarom geen basic_string<char> ?Als je alleen ascii wilt kan je gewoon std::basic_ostringstream<char> gebruiken. Anders wchar. (char is per definitie 1 byte, dit hoeven echter geen 8 bits te zijn)
Sinds wanneer is 1 byte geen 8 bits? 1 char is niet altijd 1 byte (per taal verschillend)
Verwijderd
De toString() retourneert geen char* maar een std::string. Je zult dus die std::string nog moeten omzetten naar een char*:Op vrijdag 26 juli 2002 14:13 schreef active2 het volgende:
Dit is een hele goeie oplossing maar nu zit ik met het volgende probleem:
strcpy(waarde, toString(100));
Werkt niet.
Het heeft wat met die pointers te maken maar ik weet niet hoe ik dit kan oplossen omdat ik nog nooit met die templates gewerkt heb.
1
| strcpy(waarde, toString(100).c_str()); |
Overigens is dit nog steeds riskant programmeren, je werkt nog altijd met char* en moet zelf voldoende ruimte voor je strings alloceren. Als je uitsluitend met std::string werkt heb je die problemen niet, dan gaat alles automatisch goed:
1
| string waarde= toString(100); |
Dat is het hele concept van OO. Wat is het verschil tussen een native string type en bv. std::string? Ik vind persoonlijk dat C++ perfect met strings omgaat. De standaard IO library is fantastisch.Op vrijdag 26 juli 2002 14:20 schreef Otis het volgende:
String processing is HET grote manko van C en C++ achtige talen, bij gebrek aan native stringtypes, waardoor je snel geneigd bent te gaan kijken naar classes die dat dan voor je oplossen.
Kan, maar locales zijn er ook voor om bv getallen anders te formatten. Neem USD 10,123,456.78 en INR 1,01,23,456.78 en EUR 10.123.456,78. Als je string class zelf al die varianten moet kunnen parsen wordt het een soort monolith.Locales zijn imho juist voor de interpretatie van de multibyte (unicoded) stringdata, dus of je dat soort logica in je stringclass wilt, is natuurlijk vers 2.
CString is idd een microsoft creatie en geen ISO/ANSI. Maar je kan toch heel simpel werken juist met de io lib van C++? Alle details zijn geencapsuleert in classes.ik kan me niet aan de indruk onttrekken dat de functionaliteit zoals die wordt geleverd door bv CString voor het leeuwendeel van de C++ developers die uberhaupt met strings wordt geconfronteerd meer dan genoeg is, waardoor de developer niet hoeft na te denken of de stringclass
De enige prijs in C++ is wat performance. Daarmee heb je wel uit extendable, international, platform onafhankelijke oplossing, die ook nog is heel simpel te gebruiken is. (hoeveel makelijker kan het dan std::cout << i << std::endl; ?)Veel mensen neigen ernaar om de meest algemene oplossing als de 'beste' te betitelen, maar algemenisering komt altijd met een prijs,
Ik dacht dat we het nu over formatting van unicode hadden, als je alleen een string nodig hebt, ja dan is basic_string<char> natuurlijk ook goed.waarom geen basic_string<char> ?
Sinds wanneer is 1 byte geen 8 bits? 1 char is niet altijd 1 byte (per taal verschillend)
In C++ is 1 char per iso standaard gelijk aan 1 byte. Ik dacht dat we het over C++ hadden. In Java is het idd bv 2 bytes. Heb je gelijk in. Dat van die bits was een beetje flauw, je kan in principe een machine maken waar een byte bv 9 bits is, of 32. Een byte is de minimale grootte van een geheugen unit. Maar dat is theoretisch gezwam hehe.
Verwijderd
Maar kijk hier maar eens naar:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| typedef unsigned long dword;
typedef byte err;
err str_from_dec(char *str, dword dec, dword min_digit)
{
char digits[11] = "0123456789";
dword div, dig, rdig;
if (!str)
return 0;
dig = 0;
rdig = 0;
for (div = 1000000000; div; div /= 10, rdig++)
if ((dec / div != 0) || (dig) || (div <= 1) || (10 - rdig <= min_digit))
{
str[dig] = digits[dec / div];
dec -= (dec / div) * div;
dig++;
}
str[dig] = 0;
return 1;
}
//------------------------------------------------------------------------------
err str_to_dec(char *str, dword &dec)
{
dword cur, mul, len;
if (!str)
return 0;
len = str_len(str) - 2;
if ((len > 9) || (len == -1))
return 0;
dec = 0;
mul = 1;
for (cur = 0; str[cur]; cur++)
{
if ((str[len - cur] < '0') || (str[len - cur] > '9'))
return 0;
dec += mul * (str[len - cur] - '0');
mul *= 10;
}
return 1;
} |
Volgens mij heb ik deze functies ooit sneller geschreven, dan dat jij er een bestaande methode voor hebt gevonden
Verwijderd
In principe? Het is te merken dat jullie van de PC-generatie zijnOp vrijdag 26 juli 2002 14:40 schreef Zoijar het volgende:
Dat van die bits was een beetje flauw, je kan in principe een machine maken waar een byte bv 9 bits is, of 32. Een byte is de minimale grootte van een geheugen unit. Maar dat is theoretisch gezwam hehe.
[url="http://pdp10.nocrew.org/docs/instruction-set/Byte.html"]http://pdp10.nocrew.org/docs/instruction-set/Byte.html[/url]
EeeevilText strings are typically stored using seven-bit bytes, five per word.
Haha, ja behoorlijkOp vrijdag 26 juli 2002 15:07 schreef mietje het volgende:
Eeeevil
Search hoort eigenlijk ook niet in een string, om precies de reden die je aangeeft. Dit kan nog worden getolereerd omdat search niet afhankelijk is van een willekeurig aantal andere types.Op vrijdag 26 juli 2002 14:07 schreef Otis het volgende:
[..]
C++, multiple inheritance, etc. Waarom zou een String class geen format method mogen hebben? Het is toch een method die werkt op de data IN de class, hetgeen juist is waar OO voor is bedoeld! Door multiple inheritance kun je je formatter class functionaliteit inbakken in je string class, maar dat hoeft natuurlijk niet. Een string class kan perfect een printf achtige format method hebben, iedere stringclass heeft toch ook een search functie? Of wil je dat ook als 'non-OO' afdoen want het is geen full blown regexp class?
Format daarentegen moet alle types formatten
Veel - het is bijvoorbeeld een een handig return type voor losse formatters. Andere goede reden: je kunt meer formatters hebben buiten de string class. Zo heeft mijn huidige proggie een class om SMSjes te formatten voordat ik ze naar Ben stuur, en voordat ik ze naar KPN stuur. Dat is dus geen formatter in de SMS class.Ja natuurlijk wordt de overhead groter. Je zou de string class die de format methods hebben als een is-a class derivative kunnen zien van de normale stringclass, maar no offence, wat heb je aan een stringclass zonder handige methods op de stringdata IN de class?
Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein
std::string waarde;Op vrijdag 26 juli 2002 14:13 schreef active2 het volgende:
[..]
Dit is een hele goeie oplossing maar nu zit ik met het volgende probleem:
strcpy(waarde, toString(100));
Werkt niet.
...
waarde = toString(100);
char* en = werken niet altijd zoals je verwacht. std::string en = doen dat wel.
Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein
Verwijderd
*sniff* maar ik ben helemaal niet van de patat^H^H^H^H^HPC generatie! *snik*Op vrijdag 26 juli 2002 15:07 schreef mietje het volgende:
[..]
In principe? Het is te merken dat jullie van de PC-generatie zijnVroeger werden er massa's machines geproduceerd met 7, 9, 10, 11 of nog bizardere aantallen bits-per-byte. De PDP-serie was wat dat betreft legendair.
[url="http://pdp10.nocrew.org/docs/instruction-set/Byte.html"]http://pdp10.nocrew.org/docs/instruction-set/Byte.html[/url]
/me koestert zn toshiba hx-10 memories.
Maar laten we nu maar aannemen dat een byte 8 bits is per definitie, als de basisdefinities van de bouwstenen van de definities bediscussieerd worden, dan is het einde zoek
De reden overigens waarom ASCII 7 bits is[Text strings are typically stored using seven-bit bytes, five per word.]
Eeeevil
Ja - maar die gevonden functie doet het wel op 64 bits machines. Of 16 bits. En de assembly die pak'em beet MSVC gebruikt is waarschijnlijk sneller. Dus?Op vrijdag 26 juli 2002 15:00 schreef unteraarsch het volgende:
ik snap nog steeds niet helemaal wat er bedoeld wordt...
Maar kijk hier maar eens naar:
code:
1 2 3 4 5 6 typedef unsigned long dword; typedef byte err; ... for (div = 1000000000; div; div /= 10, rdig++) ... }
Volgens mij heb ik deze functies ooit sneller geschreven, dan dat jij er een bestaande methode voor hebt gevonden
Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein
Verwijderd
Het opzoeken van een zekere index met als gegeven een substring is wel een van de operaties die je juist wilt zien in een stringclass, immers je kunt anders net zo goed zelf met een forloop een block memory doorfietsen. Jij klinkt alsof je geen methods wilt op de data die encapsulated is in het object. Lijkt me een rare zaak.Op vrijdag 26 juli 2002 15:35 schreef MSalters het volgende:
[..]
Search hoort eigenlijk ook niet in een string, om precies de reden die je aangeeft.
Nee, Format moet de mogelijkheid hebben de gegeven inputobjects om te zetten naar string. Iets dat de objects zelf moeten aangeven, of ze moeten een well known base type hebben.Dit kan nog worden getolereerd omdat search niet afhankelijk is van een willekeurig aantal andere types.
Format daarentegen moet alle types formatten
Mja, een string zonder methods teruggeven als resultaat van een method is toch een array met words of zie ik dat verkeerd? Begrijp me niet verkeerd: voor veel stringgebruik is een lightweight stringclass te prefereren en niet een kolossale class als bv CString of lookalikes. Derivatives kunnen echter in gevallen wanneer meer functionaliteit vereist is, dat gat opvullen. Ik zie niet in waarom er per se 1 string class moet zijn die nauwelijks methods heeft waar je wat aan hebt, wanneer je hem vergelijkt met een array van words.[..]
Veel - het is bijvoorbeeld een een handig return type voor losse formatters. Andere goede reden: je kunt meer formatters hebben buiten de string class. Zo heeft mijn huidige proggie een class om SMSjes te formatten voordat ik ze naar Ben stuur, en voordat ik ze naar KPN stuur. Dat is dus geen formatter in de SMS class.
Locale's zijn idd weer zo'n goede reden waarom je geen formatter in je string class wil.Op vrijdag 26 juli 2002 14:20 schreef Otis het volgende:
[..]
Mja, het zal allemaal best knap zijn, maar of het allemaal nodig is in de meeste gevallen betwijfel ik. String processing is HET grote manko van C en C++ achtige talen, bij gebrek aan native stringtypes, waardoor je snel geneigd bent te gaan kijken naar classes die dat dan voor je oplossen. Locales zijn imho juist voor de interpretatie van de multibyte (unicoded) stringdata, dus of je dat soort logica in je stringclass wilt, is natuurlijk vers 2.
Overigens is de volgende regel over multibyte/Unicode op een aantal punten fout. Multibyte strings zijn hele andere dingen als Unicode; in het eerste geval is een letter 1 of meer chars (bv Japanse shift-JIS encoding), in het tweede geval is een letter een wchar_t. Locales hebben daar niks mee te maken, die bepalen waar de '.' ( of L'.'
Ik krijg toch een beetje het idee dat je twee dingen vewart, namelijk wat er in een class wordt geleverd, en wat er bij een class wordt geleverd. Het eerste moet je namelijk altijd met die class meeslepen, het tweede alleen als je het nodig hebt. Daarom is het tweede te verkiezen voor alle functionaliteit die beperkt gebruikt wordt.Veel mensen neigen ernaar om de meest algemene oplossing als de 'beste' te betitelen, maar algemenisering komt altijd met een prijs, evenals verregaande specialisatie. Als je ziet wat voor gemak een string type in C# oplevert, wil je die functionaliteit gewoon in C++, hoe dat verder geregeld wordt zal de developer worst zijn. Of dat door een serie templates wordt geregeld of door 3 inheritance bomen, is dat nou belangrijk? Het gaat erom dat de developer een stringclass tot zn beschikking heeft die de Basic (pun intended) handelingen op een string uit kan voeren zonder morren. Dat je uiteraard wilt dat unicode support standaard is, is logisch.
Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein
En tegenwoordig zijn er GSMs met 32 bits per char. Kortom, blijf een beetje bij de tijdOp vrijdag 26 juli 2002 15:07 schreef mietje het volgende:
[..]
In principe? Het is te merken dat jullie van de PC-generatie zijnVroeger werden er massa's machines geproduceerd met 7, 9, 10, 11 of nog bizardere aantallen bits-per-byte. De PDP-serie was wat dat betreft legendair.
Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein
Nee; een array met words heeft geen memory management - en dat is IMO het cruciale verschil.Op vrijdag 26 juli 2002 15:43 schreef Otis het volgende:
Het opzoeken van een zekere index met als gegeven een substring is wel een van de operaties die je juist wilt zien in een stringclass, immers je kunt anders net zo goed zelf met een forloop een block memory doorfietsen. Jij klinkt alsof je geen methods wilt op de data die encapsulated is in het object. Lijkt me een rare zaak.
[...]
Mja, een string zonder methods teruggeven als resultaat van een method is toch een array met words of zie ik dat verkeerd? Begrijp me niet verkeerd: voor veel stringgebruik is een lightweight stringclass te prefereren en niet een kolossale class als bv CString of lookalikes.
Praktisch gezien is noch std::string noch CString een bruikbare base class. Geen van beide heeft een virtual dtor, omdat die de class significant langzamer zou maken (en in het geval van CString zelfs de normale functionaliteit onmogelijk maken). Waarom je de methods zou willen toevoegen aan een derived class als je ze ook aan een onafhankelijk formatter object kunt toevoegen is me ook niet duidelijk. Een formatter en een string hebben geen IS-A relatie.Derivatives kunnen echter in gevallen wanneer meer functionaliteit vereist is, dat gat opvullen. Ik zie niet in waarom er per se 1 string class moet zijn die nauwelijks methods heeft waar je wat aan hebt, wanneer je hem vergelijkt met een array van words.
Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein
Verwijderd
Locales zijn bij een zeker abstractieniveau nuttig, maar niet op _ELK_ abstractieniveau. Goed voorbeeld hiervan is bv de stringformatters in VBScript vs de stringformatters in C#. Dit houdt in dat je OF kiest voor een formatter die een uniforme formatdefinitiestring eet en op basis van locales de formatting doet (bv VBScript/VB6 format functies doen dat), je kunt ook kiezen voor een formatstring waar de expliciete formatteringsdefinitie in opgeslagen is, en het is aan de developer welke aangevoerd wordt. (maw: je formatter is wars van locale-related formatting issues). De een zit op een ander abstractieniveau dan de ander.Op vrijdag 26 juli 2002 15:53 schreef MSalters het volgende:
[..]
Locale's zijn idd weer zo'n goede reden waarom je geen formatter in je string class wil.
Multibyte vs Unicode is my bad idd, ik haalde MBCS en Unicode door elkaar, dat had niet gemoeten.Overigens is de volgende regel over multibyte/Unicode op een aantal punten fout. Multibyte strings zijn hele andere dingen als Unicode; in het eerste geval is een letter 1 of meer chars (bv Japanse shift-JIS encoding), in het tweede geval is een letter een wchar_t.
Mja, ik zie dit toch echt anders. OO is data-oriented, en IMHO is het t.a.t. te verkiezen op data-type X werkende functionaliteit te plaatsen in classes van data-type X of daaraan gerelateerde classes. Men praat dan wel vrolijk over universele libraries van methods, maar in feite is dat procedural denken, en niet data-oriented denken. Als je top-down over een string gaat redeneren, dan kun je in principe een core string definieren met puur memmanagenent en basic functies, en daar meerdere typen van deriven met ieders hun specialisme.[..]
Ik krijg toch een beetje het idee dat je twee dingen vewart, namelijk wat er in een class wordt geleverd, en wat er bij een class wordt geleverd. Het eerste moet je namelijk altijd met die class meeslepen, het tweede alleen als je het nodig hebt. Daarom is het tweede te verkiezen voor alle functionaliteit die beperkt gebruikt wordt.
Je kunt _OOK_ kiezen voor alleen de core string class en een serie static methods die allerlei dingen doen met een string object of meerdere string objects. IMHO echter is dit meer C-style denken dan puur OO, dataoriented. C heeft geen generics, had C die wel gehad, dan hadden we over een core class gepraat, string, en verder louter C-style code.
Om ff terug te komen op dit, 5 sec. zoeken op mijn rh machientje leerde mij dat onder linux je de functie strtol hebt met bijna dezelfde parametersOp vrijdag 26 juli 2002 10:21 schreef MSalters het volgende:
[..]
De _ aan het begin is een redelijke hint dat het een MS-only extensie is. snprintf() in C, of std::ostringstream in C++ zijn de standaard methoden, boost::lexical_cast<std::string> werkt ook
En verder wil je in C++ std::string gebruiken ipv char*
zie hier:
long int strtol(const char *nptr, char **endptr, int base);
maw. microsoft en die nog niet eens maar ik geloof borland hebben het wat logischer gemaakt en van de combi atoi - strtol de combi atoi - itoa gemaakt en het _ duidt naar mijn weten niet op zozeer op een microsoft implementatie maar meer op een "legacy" functie.
i5-12600K PRIME Z690M-PLUS D4 64GB 980 Pro M.2 1TB MBA M1 13" 8GB 256GB (Late '20)
Verwijderd
'free functions' ? Je bedoelt static methods die algemene zaken behartigen? Waarom zou je die verkiezen boven de data-oriented aanpak, die de basis vormt voor OO? Verder zie ik de theoretische basis niet voor het NIET plaatsen van zekere bewerkingsmethods op de stringclass, temeer omdat dit semantisch zeer juist zou zijn, immers, de data zit IN de class en de methods die werken OP die data zitten OOK in die class. Jij wilt ze daar niet omdat dat performance/memory kost. IMHO _nooit_ een reden voor het kiezen van wat 'juist' is, alleen in die situatie waar wat 'juist' is er niet toe doet maar performance/memory management telt (bv in de embedded wereld).Op vrijdag 26 juli 2002 16:04 schreef MSalters het volgende:
Fout, ik wil geen methods die net zo goed free functions kunnen zijn. std::search op string iterators kan precies net zo efficient zijn als een search method. Alleen die functies waarbij geheugenallocaties relevant zijn zouden dus methods moeten zijn; die allocatie strategie is nl. het enige wat een string class private moet houden.
Jouw redenatie volgend, zouden ALLE classes alleen maar met memory management moeten worden uitgerust en verder alle logica in static methods moeten worden geplaatst. Leg me aub dan eens uit waarom dat dan WEL puur OO is en de methods plaatsen IN de class (of in gespecialiseerde derivatives) niet.
Ik zei ook niet dat CString moest dienen als base class, CString is een zeer uitgebreide class en zou eerder als voorbeeld voor een specialistische derivative gelden. Waarom methods niet toevoegen aan een class en wel aan een onafhankelijke formatter? Nou omdat Object Oriented development zich richt op de data, de relaties tussen de data en de functionaliteit OP die data, niet op libraries van static functies die werken op louter baseclasses, en waarbij inheritance niet wordt gebruikt om de functionalteit die werkt op een zekere data uit te breiden maar de functionaliteit in het algemeen uit te breiden, zonder dat deze is gerelateerd aan data (dus is gesitueerd in een class).[..]
Praktisch gezien is noch std::string noch CString een bruikbare base class. Geen van beide heeft een virtual dtor, omdat die de class significant langzamer zou maken (en in het geval van CString zelfs de normale functionaliteit onmogelijk maken). Waarom je de methods zou willen toevoegen aan een derived class als je ze ook aan een onafhankelijk formatter object kunt toevoegen is me ook niet duidelijk. Een formatter en een string hebben geen IS-A relatie.
Maar dit glijdt af naar een 'wat is OO' discussie en dat is een dead-beat-horse.
Ascii TO IntOp vrijdag 26 juli 2002 16:40 schreef ghostrdr01 het volgende:
[..]
Om ff terug te komen op dit, 5 sec. zoeken op mijn rh machientje leerde mij dat onder linux je de functie strtol hebt met bijna dezelfde parameters
zie hier:
long int strtol(const char *nptr, char **endptr, int base);
STRint TO Long
Niet echt een heel verschil he?
atoi is gewoon makkelijker (in C) omdat je weet dat er sizeof(int) bytes uitkomen, van itoa weet je dat niet a priori.
C++ers gebruiken gewoon boost::lexical_cast van en naar std::string, dat is pas symmetrisch
Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein
Verwijderd
Nee, ik bedoel free functions buiten de class, die NIET met de class internals rotzooien. Als je een bug in een class wil lokaliseren, waardoor private members veranderen, hoef je alleen members te doorzoeken. Hoe minder members hoe beter. Static members hebben access privileges op private members/methods. Free functions die dezelfde functionalieit bieden zijn daarom te verkiezen (zie ook Scott Meyers)Op vrijdag 26 juli 2002 16:42 schreef Otis het volgende:
'free functions' ? Je bedoelt static methods die algemene zaken behartigen? Waarom zou je die verkiezen boven de data-oriented aanpak, die de basis vormt voor OO?
Laat ik even aannemen dat je bedoelde "zelden een doorslaggevende reden".Verder zie ik de theoretische basis niet voor het NIET plaatsen van zekere bewerkingsmethods op de stringclass, temeer omdat dit semantisch zeer juist zou zijn, immers, de data zit IN de class en de methods die werken OP die data zitten OOK in die class. Jij wilt ze daar niet omdat dat performance/memory kost. IMHO _nooit_ een reden voor het kiezen van wat 'juist' is, alleen in die situatie waar wat 'juist' is er niet toe doet maar performance/memory management telt (bv in de embedded wereld).
Mijn primaire reden is dat de complexiteit van software vereenvoudigd wordt als er meer onafhankelijke entiteiten met beperkte interfaces zijn. Een free function is op die manier simpeler omdat deze alleen bij de publieke data interface kan.
Nee, alleen classes die memory management uitvoeren horen zich te beperken tot memory management. String is zo'n class die memory management doet voor chars.Jouw redenatie volgend, zouden ALLE classes alleen maar met memory management moeten worden uitgerust en verder alle logica in static methods moeten worden geplaatst.
Als ik een C programma neem, en ik plaats alle functies daarvan in een class (als [static] methods) is dat dan OO?Leg me aub dan eens uit waarom dat dan WEL puur OO is en de methods plaatsen IN de class (of in gespecialiseerde derivatives) niet.
Nee, natuurlijk niet. OO heeft niets te maken met de plaatsing van dit soort functies. OO gaat veel meer over het bewaken van invarianten, zoals "de string class weet op elk moment hoeveel chars er gemanaged worden" en "de string class kan op elk moment alle chars dealloceren".
Precies! Je slaat hiet de spijker op z'n kop. Een formatteer actie legt de relatie tussenWaarom methods niet toevoegen aan een class en wel aan een onafhankelijke formatter? Nou omdat Object Oriented development zich richt op de data, de relaties tussen de data en de functionaliteit OP die data, niet op libraries van static functies die werken op louter baseclasses, en waarbij inheritance niet wordt gebruikt om de functionalteit die werkt op een zekere data uit te breiden maar de functionaliteit in het algemeen uit te breiden, zonder dat deze is gerelateerd aan data (dus is gesitueerd in een class).
1) een aantal input objecten
2) een format specificatie
3) het eindresultaat ( een string ).
Deze functie toewijzen aan 3 is wel bijzonder vreemd. Als het al ergens bijhoort is het wel bij 2. En je ziet dus dat nieuwere C++ voorstellen voor formatters eruitzien als
1
2
3
4
| format pair("(%2 %1)"); std::string output_num = pair(3,4); std::string output_text = pair("A","B"); |
Hierin is pair een formatter object, met als formatting functie operator(). De output is dus de strings "(4 3)" en "(B A)".
Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein
Als voorbeeld met die string, je gaat dus niet een basis string class maken, en daar nieuwe classes van afleiden die specifieke formatting doen (stel even dat je de formatting in de string class zou plaatsen). Je krijgt dan een soort explosie van string classes, en onderlinge dependencies.
Het is veel beter om dan enkele kleine classes te schrijven, ofwel policies, en je string af te leiden van de policy classes die je nodig hebt via multiple inheritance. Je reduceert je afhankelijkheden dan.
Als je nog verder gaat, zou het ideaal zijn als je dit soort dingen compleet buiten de string class kan halen. Het begrip van encapsulatie/data hiding gaat niet alleen op voor de eindgebruiker, maar ook tussen classes. Zo min mogelijk code moet toegang hebben tot private members.
In de standaard library zie je al deze concepten heel duidelijk naar voren komen. Misschien is dit boek een aanrader, als je het C++ IO model eenmaal echt door hebt, zie je in hoe mooi het in elkaar zit.
"Standard C++ IOStreams and Locales: Advanced Programmer's Guide and Reference" by Angelika Langer, Klaus Kreft
Verwijderd
Dat komt door de taaltechnische voordelen die C++ en ook sommige andere talen bieden die wel met de OO-gerelateerde methodieken te maken hebben maar niet met OO-denken. Ach, op zich is het niet zo'n probleem, vind ik.Op vrijdag 26 juli 2002 17:55 schreef Zoijar het volgende:
Het is een bekend feit dat veel C++ers te vaak en te veel inheritance gebruiken, en dan ook vaak nog naar de verkeerde kant.
Erm, wat is nou de preciese reden waarom niet? Want als we puur naar de algemene OO methodiek kijken wanneer je normaliter een class subclasset, is het wel degelijk semantisch correct om te veronderstellen dat je op basis van een karige base-class dmv generics bijvoorbeeld, gespecialiseerde subclasses maakt. Ik zie niet in waarom een string daar dan niet aan zou moeten voldoen. IEDERE specialisatie van een class levert wellicht meerdere subclasses op en indien je middels generics deze classes implementeert, krijg je een wellicht grote hoeveelheid verschillende. Dat is inherent aan baseclass-subclass.Als voorbeeld met die string, je gaat dus niet een basis string class maken, en daar nieuwe classes van afleiden die specifieke formatting doen (stel even dat je de formatting in de string class zou plaatsen). Je krijgt dan een soort explosie van string classes, en onderlinge dependencies.
Multiple inheritance vergroot toch juist afhankelijkheden, of zie ik het verkeerd?Het is veel beter om dan enkele kleine classes te schrijven, ofwel policies, en je string af te leiden van de policy classes die je nodig hebt via multiple inheritance. Je reduceert je afhankelijkheden dan.
Wat mijn punt is, is dat er een uitzonderingspositie schijnt te moeten worden gemaakt voor de 'formatting' method bij een 'string' class. Dit lijkt me echter onzin, daar bv het resultaat van de formatting method de inhoud van het stringobject bepaalt, en dus wel degelijk net als een assignment operator thuis hoort in de stringclass (of een concatoperator die de right operand plakt achter de huidige toestand van de stringclass). Waarom zou dan de formatting method niet thuis horen in de string class? Omdat er dan vele stringclasses komen? Mja, maar daar is toch 'generics' voor uitgevonden?
Een format method doet toch net als een assignment operator iets met de classcontents? ALs je de format BUITEN de stringclass haalt, is dat dus een method die dus niet alleen strings op hoeft te leveren maar ook een ander type. In _DIE_ algemeenheid, ja, dan is dat logisch, echter levert je formattingclass alleen strings op, waarom zit die functionaliteit niet in de stringclass zelf (of een derived versie)? Immers hij is onlosmakelijk verbonden met de stringclass en werkt op de inhoud van de stringclass. Hoe kun je een method A (formatting) dan wel buiten de stringclass halen en een method B (assignment) niet, terwijl beide de contents van de class bepalen. Een formatting is toch niets anders dan een speciale assignment.Als je nog verder gaat, zou het ideaal zijn als je dit soort dingen compleet buiten de string class kan halen. Het begrip van encapsulatie/data hiding gaat niet alleen op voor de eindgebruiker, maar ook tussen classes. Zo min mogelijk code moet toegang hebben tot private members.
Ik zou liever zien dat C++ meer typen en statements kreeg die de std overbodig maken. De std is een knap staaltje werk, maar als je kijkt naar bv het gemak van java en C# en je vergelijkt dat met C++, dan zou je soms willen dat dat gemak (tezamen met het gemak van C++In de standaard library zie je al deze concepten heel duidelijk naar voren komen. Misschien is dit boek een aanrader, als je het C++ IO model eenmaal echt door hebt, zie je in hoe mooi het in elkaar zit.
"Standard C++ IOStreams and Locales: Advanced Programmer's Guide and Reference" by Angelika Langer, Klaus Kreft
Ik denk dat we van mening verschillen omtrent wat je in een class bundelt en waarom. Het is niet 'goed vs fout', maar meer verschillende visies op dit thema. Immers, je kunt er idd voor pleiten een serie algemene classes te definieren die bulkwerk uit handen nemen, en omdat je die met generics opzet zijn ze overal inzetbaar en ontlast je de doorgaans veelgebruikte andere classes die daardoor lichter worden. Anderen, waaronder yours truely
Verwijderd
Ja ok, maar die functies zitten ergens in, ik neem aan static. Dat bedoelde ik. Niet static in bv de stringclassOp vrijdag 26 juli 2002 17:23 schreef MSalters het volgende:
[..]
Nee, ik bedoel free functions buiten de class, die NIET met de class internals rotzooien. Als je een bug in een class wil lokaliseren, waardoor private members veranderen, hoef je alleen members te doorzoeken. Hoe minder members hoe beter. Static members hebben access privileges op private members/methods. Free functions die dezelfde functionalieit bieden zijn daarom te verkiezen (zie ook Scott Meyers)
Mij hoor je ook niet zeggen dat procedureel denken foutief is oid[..]
Laat ik even aannemen dat je bedoelde "zelden een doorslaggevende reden". Mijn primaire reden is dat de complexiteit van software vereenvoudigd wordt als er meer onafhankelijke entiteiten met beperkte interfaces zijn. Een free function is op die manier simpeler omdat deze alleen bij de publieke data interface kan.
Het is denk ik wat je prefereert. Ik kom uit de C wereld en ken de ellende van functies die wel ergens bijhoorden maar je kon dat behalve middels modules niet echt kenbaar maken.
Agreed, maar ik wil ook graag een simpele class die dat doet wat die string class doet van jou PLUS basic stringhandling zoals concatenation, simpele formatting, splitting enz., je weet wel, die dingen die bij string-intensieve code een slok op een borrel schelen[..]
Nee, alleen classes die memory management uitvoeren horen zich te beperken tot memory management. String is zo'n class die memory management doet voor chars.
mja, zoalsik zei: 'wat is OO' ligt op de loer, dus daar ga ik niet in mee[..]
Als ik een C programma neem, en ik plaats alle functies daarvan in een class (als [static] methods) is dat dan OO?
Nee, natuurlijk niet. OO heeft niets te maken met de plaatsing van dit soort functies. OO gaat veel meer over het bewaken van invarianten, zoals "de string class weet op elk moment hoeveel chars er gemanaged worden" en "de string class kan op elk moment alle chars dealloceren".
NEE![..]
Precies! Je slaat hiet de spijker op z'n kop. Een formatteer actie legt de relatie tussen
1) een aantal input objecten
2) een format specificatie
3) het eindresultaat ( een string ).
Deze functie toewijzen aan 3 is wel bijzonder vreemd. Als het al ergens bijhoort is het wel bij 2.
De formatter is niet een functie zoals printf dat is! Dan had je gelijk. De formatter is een speciale assigment functie. '=' doet geen formatting en maakt de right operand als inhoud van het string object, 'Format()' doet eerst een formatting van de parameters en maakt het resultaat de inhoud van het string object.
Zie je het als algemene gehaktmolenfunctie, dus duw er iets in en er komt een string uit, wat je er mee doet moet je zelf weten, ja, dan is het plaatsen bij de string bediscussieerbaar. Zie je het als een internal assignment functie, zoals het ook in bv CString is geimplementeerd, dan is dit heel wat anders en een pure method op de interne class' data, zoals dat bij OO gebruikelijk is.
Verwijderd
Het voordeel van een library-georienteerde taal tov. een keyword-georienteerde taal is dat de (basis)taal daardoor veel breder inzetbaar wordt. C++ probeert de gebruikersvriendelijkheid van een keyword-georienteerde taal te benaderen door de mogelijkheid keywords (operatoren) te overloaden.Op vrijdag 26 juli 2002 18:18 schreef Otis het volgende:
Ik zou liever zien dat C++ meer typen en statements kreeg die de std overbodig maken. De std is een knap staaltje werk, maar als je kijkt naar bv het gemak van java en C# en je vergelijkt dat met C++, dan zou je soms willen dat dat gemak (tezamen met het gemak van C++) gebundeld werd.
Het invoeren van string als een atomair type (ik neem aan dat je dat bedoelt) in een taal vind ik een draak, want een string is geen atomair type maar een geordende verzameling karakter-atomairen.
Onder de streep is het enige verschil dat een applicatieprogrammeur opmerkt tussen een keyword-aanpak en een overloading plus library-aanpak, het feit dat hij headers moet includen en de bewuste libraries mee moet linken.
Ook OOP is een kwestie van afwegen hoe ver je je software "doordesigned", maw. hoe ver dat je je probleem abstraheert. Zo kun je er om verschillende redenen voor pleiten bepaalde zware actor-methods op een object verder te abstraheren tot zelfstandige actor-objects, zoals MSalters dat doet. Dat is geheel in de geest van OOD.Ik denk dat we van mening verschillen omtrent wat je in een class bundelt en waarom. Het is niet 'goed vs fout', maar meer verschillende visies op dit thema. Immers, je kunt er idd voor pleiten een serie algemene classes te definieren die bulkwerk uit handen nemen, en omdat je die met generics opzet zijn ze overal inzetbaar en ontlast je de doorgaans veelgebruikte andere classes die daardoor lichter worden. Anderen, waaronder yours truely, vinden dit toch meer een uitholling van het pure OO / dataoriented denken. C'est la vie.
Verwijderd
Op zich is hier wel veel voor te zeggen, ik vind C++ er alleen niet vriendelijker op worden als je kijkt wat je moet kennen van de std wil je er effectief gebruik van maken. Je zit dan met 2 gedeelten die je moet leren: EN C++ EN de std.Op vrijdag 26 juli 2002 18:43 schreef mietje het volgende:
[..]
Het voordeel van een library-georienteerde taal tov. een keyword-georienteerde taal is dat de (basis)taal daardoor veel breder inzetbaar wordt. C++ probeert de gebruikersvriendelijkheid van een keyword-georienteerde taal te benaderen door de mogelijkheid keywords (operatoren) te overloaden.
Mja, een float is in theorie ook een type bestaand uit een aantal onderdelen. Dezelfde discussie woedde een week geleden in de C# newsgroep omtrent de struct als valuetype, of dat nu wel of niet een goed ding was. Ik vind van wel, een Complex number type kun je dan toch atomair behandelen alsof het een valuetype is. Met strings is het imho net zo, immers, je behandelt ze altijd als valuetypes. (In .NET cheaten ze hoor, ze doen onder water gewoon new System.String(value)) Dat men sinds mensenheugenis strings ziet als arrays van chars of soortgelijke elements, is IMHO een leftover van het fenomeen dat de talen van weleer geen ingebakken stringtype hadden. Echter voor de developer maakt het toch niet uit HOE de compiler en de RTL er mee omgaan, het gaat om het feit dat mensen op een abstract niveau met strings kunnen omgaan zonder de overhead die er anders altijd mee gemoeid is.Het invoeren van string als een atomair type (ik neem aan dat je dat bedoelt) in een taal vind ik een draak, want een string is geen atomair type maar een geordende verzameling karakter-atomairen.
Wat is voor de gebruiker het verschil tussen, zeg een class Complex, en een build-in type Complex? Je kan in C++ perfect een class maken die zich volledig gedraagt als value type. C++ heeft het zeg maar allemaal, je kan zelf nieuwe types toevoegen. Ik zie een string niet als array van characters hoor als ik dat niet wil. Het is gewoon een std::string en daar kan je dingen mee doen, zoals die string bv naar output sturen. En ik reken met quaternions alsof het floats zijn zeg maar. Ik zie niet in waarom je steeds met dit verschil aan komt, wat het voordeel (nadeel!) is van build-in types.Op vrijdag 26 juli 2002 20:29 schreef Otis het volgende:
Ik vind van wel, een Complex number type kun je dan toch atomair behandelen alsof het een valuetype is. Met strings is het imho net zo, immers, je behandelt ze altijd als valuetypes. (In .NET cheaten ze hoor, ze doen onder water gewoon new System.String(value)) Dat men sinds mensenheugenis strings ziet als arrays van chars of soortgelijke elements, is IMHO een leftover van het fenomeen dat de talen van weleer geen ingebakken stringtype hadden. Echter voor de developer maakt het toch niet uit HOE de compiler en de RTL er mee omgaan, het gaat om het feit dat mensen op een abstract niveau met strings kunnen omgaan zonder de overhead die er anders altijd mee gemoeid is.
Verwijderd
Agreed (hoewel ik de STL eigenlijk als een integraal onderdeel van C++ beschouw). Op zich zit de STL erg logisch in elkaar, meestal is het overschakelen op generic programming in het algemeen het struikelblok, dat is conceptueel toch iets moeilijker dan OO. De std::string is echter niet lastiger te hanteren dan bv. een Pascal String.Op vrijdag 26 juli 2002 20:29 schreef Otis het volgende:
Op zich is hier wel veel voor te zeggen, ik vind C++ er alleen niet vriendelijker op worden als je kijkt wat je moet kennen van de std wil je er effectief gebruik van maken. Je zit dan met 2 gedeelten die je moet leren: EN C++ EN de std.
Met strings is het imho net zo, immers, je behandelt ze altijd als valuetypes.
Mja, ik doelde het meer op het conceptuele verschil. Hoewel een float intern uit mantissa en exponent bestaat, zal een applicatieprogrammeur die onderdelen nooit individueel benaderen willen. Bij een string kun je er donder op zeggen dat er vroeger of later een applicatieprogammeur is die toegang nodig heeft tot de individuele karakters van die string. En zoals gezegd, de overhead blijft veelal beperkt tot "#include <string>".Echter voor de developer maakt het toch niet uit HOE de compiler en de RTL er mee omgaan, het gaat om het feit dat mensen op een abstract niveau met strings kunnen omgaan zonder de overhead die er anders altijd mee gemoeid is.
(2x "conceptueel" en 1x "integraal" in een post gebruikt, ik ontkom blijkbaar ook niet aan taal-hypes
Verwijderd
Het passen van een instance aan een functie is verschillend. Value types zijn altijd by value, classes impliceren objects en die zijn altijd by reference.Op vrijdag 26 juli 2002 20:59 schreef Zoijar het volgende:
[..]
Wat is voor de gebruiker het verschil tussen, zeg een class Complex, en een build-in type Complex?
Een class is een object en bij mijn weten heb je dan altijd een pointer naar een vtable en geen value type die in het stackframe is gealloceerd. Hierdoor krijg je wel degelijk verschillend gedrag bij het heen en weer gooien van instances tussen functies.Je kan in C++ perfect een class maken die zich volledig gedraagt als value type. C++ heeft het zeg maar allemaal, je kan zelf nieuwe types toevoegen.
het voordeel van build-in types is dat iedereen die de taal kent, de types ook kent. Iemand die niet de stijle leercurve van de std door wil maar bv middels OWL of MFC of weet ik wat voor lib met C++ bezig is, begrijpt je niet als jij iets uit de std aanvoert, terwijl jij dat beschouwt als onderdeel van C++. Met build-in types heb je dat dus niet. C++ heeft gaten in de functionaliteit op het gebied van buildin types, hoe die intern ook worden opgelost. De std vangt die allemaal op, maar zoals gezegd, zonder std is het nog steeds goed mogelijk C++ te programmeren (hell, veel win32 developers die programmeren in C++ gebruiken MFC's classes (v6 of hoger) en atl. Je krijgt dan tweedeling in de gebruikers van 1 taal, terwijl beide groepen dezelfde functionaliteit nastreven. (Los van het feit of valuetypes van structs handig zijn of nietIk zie een string niet als array van characters hoor als ik dat niet wil. Het is gewoon een std::string en daar kan je dingen mee doen, zoals die string bv naar output sturen. En ik reken met quaternions alsof het floats zijn zeg maar. Ik zie niet in waarom je steeds met dit verschil aan komt, wat het voordeel (nadeel!) is van build-in types.
void foo(int& i) {} // value type by referenceOp vrijdag 26 juli 2002 21:57 schreef Otis het volgende:
Het passen van een instance aan een functie is verschillend. Value types zijn altijd by value, classes impliceren objects en die zijn altijd by reference.
void bar(Complex c) {} // object by value
De standaard zegt niets over vtables, dus kan je er in principe geen uitspraken over doen. (maar iha als er niets virtueel is optimized je compiler het eruit)Een class is een object en bij mijn weten heb je dan altijd een pointer naar een vtable en geen value type die in het stackframe is gealloceerd. Hierdoor krijg je wel degelijk verschillend gedrag bij het heen en weer gooien van instances tussen functies.
Overigens zegt de standaard ook niets over de (byte) grootte van build in types, muv char.
Als je dus volledig via de standaard werkt, zie je ook op het stackframe geen verschil. Een array van complex ziet er hetzelfde uit als een array van int. Misschien niet in je geheugen, maar dat mag je toch niet rechtsreeks aanspreken want dan ben je al niet portable bezig.
Iedereen behoort ook de standaard library te kennen, net als je in andere talen de build-in types moet kennen. Dat mensen bv mfc en atl en win32 en std mixen heb je gelijk in, en dat is ook slecht. De leer curve is misschien hoog ja, maar niemand heeft gezegd dat C++ een makkelijke taal is.het voordeel van build-in types is dat iedereen die de taal kent, de types ook kent.
Verwijderd
Ik drukte me wat te algemeen uit, in C++ heb je memberwise copies die als 'by value' dienen, klopt. En ja valuetypes passen by reference ken ik, ik bedoelde meer: value types declareer je op de stack, reference types definieer je op de heap. Objects zijn normaliter reference types en definieer je dus niet op de stack maar op de heap. Dit deel van de discussie ging over het nut van value types. so there.Op vrijdag 26 juli 2002 22:15 schreef Zoijar het volgende:
[..]
void foo(int& i) {} // value type by reference
void bar(Complex c) {} // object by value
Huh? waar staat dat geschreven? Lekkere taal, naast de taal, en de api die je gebruikt voor platformaccess heb je ook nog te maken met een 3e tak van sport, de std, die moet je ook kennen, volgens de purist[..]
Iedereen behoort ook de standaard library te kennen, net als je in andere talen de build-in types moet kennen.
Slecht, volgens wie? Een programmeertaal en libraries gebruik je om een zeker doel te bereiken, niet voor de kicks.Dat mensen bv mfc en atl en win32 en std mixen heb je gelijk in, en dat is ook slecht.
Dat was ook niet het punt.De leer curve is misschien hoog ja, maar niemand heeft gezegd dat C++ een makkelijke taal is.
Verwijderd
Waar heb je dit vandaanOp vrijdag 26 juli 2002 23:54 schreef Otis het volgende:
Objects zijn normaliter reference types en definieer je dus niet op de stack maar op de heap.
Voor zover ik weet is er helemaal niks mis met het gebruiken van de stack voor non-built-in's.
Verwijderd
Voor piepkleine struct/classes zou dat ook niet zo onlogisch zijn, echter waarom zou MS speciaal voor de managed C++ extensions '__value' hebben geintroduceerd om value typed classes te kunnen maken die je naast de runtime heap ook op de stack kunt plaatsen en zo ervoor te zorgen dat de GC niet deze, kleine, classes op hoeft te ruimen? Als je sowieso classes al op de stack kon plaatsen, waarom zou dan dit keyword nodig zijn?Op zaterdag 27 juli 2002 00:24 schreef Sneechy het volgende:
[..]
Waar heb je dit vandaan
Voor zover ik weet is er helemaal niks mis met het gebruiken van de stack voor non-built-in's.
Het is ook niet zo onlogisch hoor, om objectinstances niet op de stack te alloceren maar op de runtime heap. Voor de developer maakt dat niet zoveel uit natuurlijk.
Hmmm, bij nader inzien flikkert de VC++ compiler wel degelijk grote objects op de stack ipv alleen de vtable + membertable. Odd.
Stack en heap allocatie kan je helemaal zelf bepalen, je hebt zelfs nog placement-new in C++, waarmee er alleen heap geheugen wordt gealloceerd en je zelf je object erin kan plaatsen.Op zaterdag 27 juli 2002 11:30 schreef Otis het volgende:
die je naast de runtime heap ook op de stack kunt plaatsen en zo ervoor te zorgen dat de GC niet deze, kleine, classes op hoeft te ruimen? Als je sowieso classes al op de stack kon plaatsen, waarom zou dan dit keyword nodig zijn?
Je kan een int op de heap zetten, en ook een CVeryBigClass op de stack. Vaak zet je een object op de heap, en een auto pointer ernaar op de stack.
En verder heeft C++ geen GC
Het maakt wel degelijk uit aangezien er geen GC is. Stack wordt netjes opgeruimd, heap niet. De normale gang van zaken is om een smart pointer (std::auto_ptr) naar een heap gealloceerd object op de stack te zetten.Het is ook niet zo onlogisch hoor, om objectinstances niet op de stack te alloceren maar op de runtime heap. Voor de developer maakt dat niet zoveel uit natuurlijk.
edit:
Hmmm, bij nader inzien flikkert de VC++ compiler wel degelijk grote objects op de stack ipv alleen de vtable + membertable. Odd.