Sign in to follow this  

Strings

This topic is 4482 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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...)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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<char> cStringC;
typedef cString<unsigned short> 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.

Share this post


Link to post
Share on other sites

This topic is 4482 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this