Skip to main content
GameDev.net gamedev.net
🔒 Locked

Strings

Started by Skute Sep 5, 2005 at 3:37 PM 9 replies 2.2k views
Original Post
Skute
Skute
Quick question: Custom string class vs LPCTSTR ? Ive got a custom class which wraps around TCHAR*, but im worried it might have a slight speed impact, rather than pass around the raw string pointer (TCHAR*). What do you think? The class is well written and uses standard crt functions for copying / concatenation etc. Thanks
Mark Ingramhttp://www.mark-ingram.com
Fruny
Fruny
How many string operations are you doing per second?
Why are you not using the standard C++ std::string class?
You can pass parameters by reference or const reference if you're afraid of the copy costs.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
CTar
CTar
Since you are talking about making your own class I assume you use C++ (right?). I'ld recommend you to use the SC++L's string class instead of your own or raw pointers.

You will very quickly experience problems if you keep passing TCHAR* pointers.
Skute
Skute
i definately not copying objects with each call, i try to pass everything by reference.

there arent that many string operations going on at all, its more for logging stuff, printing stuff to screen every now and then etc.

not sure why im not using std::string, may have a quick look at that...
Mark Ingramhttp://www.mark-ingram.com
blizzard999
blizzard999
I derived my string class from std::string and introduced an LPCSTR operator.

operator LPCSTR()const{ return c_str(); }


I dont know if this is correct for the purists but it works and I like it.

Also I dont know why this casting was not implemented (I'm sure there is a reason...)
Glak
Glak
yes there is a reason that automatic conversion to char* is not part of std::string.

string s("hi");
cout<< s+" there"<cout<
The above example does not compile. Sure that '-' would stand out but what if the surrounding code were more complex and you were really tired? You might never notice that you typed a - instead of a +. However that is ok, you get an error message and you fix the problem in a few seconds.

Now consider what happens if you can convert to char*. There is no error message. Instead s.c_str() is called returning a pointer, then some pointer math is done and cout prints some gibberish. However in your real world program you aren't printing to cout, instead you're sending data through a socket stream class that you designed, or to a save game file. Now you start wondering why the networking doesn't work, or that save file won't load correctly. So that is why you have to call c_str(). C++ is a pretty big language and there are lots of things that you can do wrong, however great pains have been taken so that you won't accidentally do something wrong that compiles.
Thunder_Hawk
Thunder_Hawk
Quote:
Original post by Glak
yes there is a reason that automatic conversion to char* is not part of std::string.

string s("hi");
cout<< s+" there"<cout<
The above example does not compile. Sure that '-' would stand out but what if the surrounding code were more complex and you were really tired? You might never notice that you typed a - instead of a +. However that is ok, you get an error message and you fix the problem in a few seconds.

Now consider what happens if you can convert to char*. There is no error message. Instead s.c_str() is called returning a pointer, then some pointer math is done and cout prints some gibberish. However in your real world program you aren't printing to cout, instead you're sending data through a socket stream class that you designed, or to a save game file. Now you start wondering why the networking doesn't work, or that save file won't load correctly. So that is why you have to call c_str(). C++ is a pretty big language and there are lots of things that you can do wrong, however great pains have been taken so that you won't accidentally do something wrong that compiles.


You have a good point about that conversion operator being a bad thing, and I would probably extend that argument to conversion operators in general.

However, I'd like to point out that my keyboard (not sure where you're from) makes it kind of difficult to confuse - and +: You not only have to forget to press SHIFT, but you also have to press a completely different key (albeit, they're right next to each other). If you're using the numpad, on the other hand, the + key is about three times the size of the - key and is generally hit on the bottom (which is hard to mistake from the - key's "lofty" position).
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Forma
Kitt3n
Kitt3n
This one is also 'funny':

std::string stlstr;
char mystr[1000];
sprintf (mystr, "%s: %d", stlstr, 10); // <= CRASH, forgot .c_str()

I fixed several crashes with sth like this in my project :)

I know - you _should_ use cout, but if you want to get eg float
with limited precision (sth like %7.3f), then it gets really nasty
and difficult to read imho - so I prefer sprintf.

/R
visit my website at www.kalmiya.com
MaulingMonkey
MaulingMonkey
Quote:
Original post by Kitt3n
This one is also 'funny':

std::string stlstr;
char mystr[1000];
sprintf (mystr, "%s: %d", stlstr, 10); // <= CRASH, forgot .c_str()

I fixed several crashes with sth like this in my project :)

I know - you _should_ use cout, but if you want to get eg float
with limited precision (sth like %7.3f), then it gets really nasty
and difficult to read imho - so I prefer sprintf.


You may be interested in the boost library collection [link]. You could transform the above into:

std::string stlstr;
std::string mystr;
mystr = str( boost::format( "%s: %d" ) % stlstr % 10 );

In case you couldn't guess from the identical format specifiers, boost::format supports a lot of the printf style options. Plus it's typesafe and argument-count safe - it'll throw boost::io::too_many_args if you pass too many, or boost::io::too_few_args if you pass too few - instead of randomly corrupting the stack or other such wonderful possibilities.
noNchaoTic
noNchaoTic
i normally roll with a templatized string class... lots of people are like WHY THE HELL? I then provide a couple of typedefs in the form of

typedef cString cStringC;
typedef cString cStringU;

have built in support for unicode strings then.
Steven ToveySPUify | Twitter
snk_kid
snk_kid
Quote:
Original post by noNchaoTic
... lots of people are like WHY THE HELL? I then provide a couple of typedefs in the form of

typedef cString cStringC;
typedef cString cStringU;

have built in support for unicode strings then.


[headshake] if didn't already know std::string is just a type alias (a typedef) for std::basic_string, a class template, parameterized by character type and character traits and allocator type where the character traits & allocator type have defaults (std::char_traits & std::allocator).

Also just using wide character strings doesn't mean you automagically have unicode support and oh you wouldn't normally use unsigned short directly for wide characters you would use wchar_t even if wchar_t is a type alias for unsigned short.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.