Strings

Started by
9 comments, last by snk_kid 18 years, 7 months ago
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
Advertisement
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
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.
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
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...)
yes there is a reason that automatic conversion to char* is not part of std::string.

string s("hi");
cout<< s+" there"<<endl; //prints "hi there"
cout<<s-" there"<<endl; //oops, accidentally forgot to hold down shift!

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.
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"<<endl; //prints "hi there"
cout<<s-" there"<<endl; //oops, accidentally forgot to hold down shift!

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 Formats______________________________________________________________________________________
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
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.
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<char> cStringC;
typedef cString<unsigned short> cStringU;

have built in support for unicode strings then.
Steven ToveySPUify | Twitter

This topic is closed to new replies.

Advertisement