std::string, classes and... pointer?

Started by
14 comments, last by kVandaele 20 years, 2 months ago
Congratulations, nice going!

-hellz
Advertisement
quote:Original post by bastardos

I''m sorry zahlman, but you''re incorrect. The prototype of the sprintf is:

int sprintf ( char * buffer, const char * format [ , argument , ...] );

The second argument is the format string.


I knew that much; I figured it would work fine because there aren''t any %''s in his string. Of course, somehow I missed the part where a C-style function isn''t going to accept a std::string where a const char * is expected :/

... oh wait, he did put in the .c_str(), so it should be fine. But then what''s the point of doing the sprintf step at all?

So now then, kVandaele:

Your printing wrapper doesn''t change the string (I hope!!!) so all you really need is

App->m_Font.Print(App->m_Total.GetNowString(tempText).c_str(), TIMEDISPLAY_XLOC, TIMEDISPLAY_YLOC); 


quote:
As you can see, DrawText takes a Long Pointer to C STRing (... i think). So, even if i modified the cFont.Print class to take a std::string variable, at some point i''d have to convert anyway.


Do it as close to the 3rd-party call as possible, i.e. in your Print class in this case. This is in conformance with the principle of "Once and only once", letting you deal with nice happy std::strings all over your own code, writing, you know, actual C++ instead of C.

quote:
I get where passing the variable to it doesn''t do anything, but i do return s, and then doesn''t this line call the c_str() of the returned std::string?
App->m_Total.GetNowString(tempText).c_str()
= s.c_str() ?


The form I suggested above will make use of the return value. The line you''re proposing now doesn''t even have a valid lvalue, as far as I can tell.

But the whole thing with having to pass in a string so that you''re not returning a reference to a local variable... it''s quite valid to have a function that expects and uses a "scratch" buffer like that, but it''s IMHO rather C-stylish. The usual Java way at least would be to have getNowString take no parameters and return a newly allocated string. Though in C++ that may not be such a good idea because of the lack of built-in garbage collection (it will be hard to track that memory).

Might I suggest as a compromise: have a "static string buffer;" added to your cTotal class, which is used as the scratch space for this function. Each time the getNowString() method (now with no args - simplifying your interfaces is a good thing!) is called, it will rewrite the contents of the buffer (which is ok, because they''re normally not visible to the rest of the world) and return a reference thereto. As a bonus (of dubious value), the implementation of "getLastTimeString()" becomes trivial.

WARNING: that won''t be thread-safe. You need to either be very careful about synchronization (probably more work than it''s worth), or set up a separate buffer for each thread.
quote:Original post by VolkerG
To Zahlman: The rhs of the s+= is a character pointer, no std::string appearing here.


... but it''s the lhs of an operator that defines the overloaded behaviour, and apparently there exists something like

std::string & std::string::operator+= (const char *)

, otherwise the OP would be telling us that the damn thing didn''t compile. Right? o__O
>>... oh wait, he did put in the .c_str(), so it should be fine. But then what''s the point of doing the sprintf step at all?

Because my cFont:rint was defined as such:
BOOL cFont:rint(char *Text, long XPos, long YPos, long Width, long Height, D3DCOLOR Color, DWORD Format);
And as you know, char* Text won''t accept a const char*...

However, since DrawText DOES accept a const char*, and drawtext is what''s used in cFont:rint, i added another Print member function defined as such:
BOOL cFont:rint(std::string Text, long XPos, long YPos, long Width, long Height, D3DCOLOR Color, DWORD Format);
Oh happy day

quote:Your printing wrapper doesn''t change the string (I hope!!!) so all you really need is


App->m_Font.Print(App->m_Total.GetNowString(tempText).c_str(), TIMEDISPLAY_XLOC, TIMEDISPLAY_YLOC);

Actually, like i said before, it would complain because c_str() returns a const char*, and it needs a char*. However, (directX''s) DrawText DOES accept a const char*, so i solved it with a new Print function, like the afore mentioned.

I''m too stupid (... well, inexperienced really) to always follow "Once And Only Once", but in this case i did. I think.

Actually multiple threads is a subject still way ahead of me.

A little late now that it''s fixed with stringstream, but in theory, if the int''s are interpreted as non-text, wouldn''t a call to itoa(int) have solved the whole thing?
quote:Original post by kVandaele
quote:Your printing wrapper doesn't change the string (I hope!!!) so all you really need is


App->m_Font.Print(App->m_Total.GetNowString(tempText).c_str(), TIMEDISPLAY_XLOC, TIMEDISPLAY_YLOC);


Actually, like i said before, it would complain because c_str() returns a const char*, and it needs a char*. However, (directX's) DrawText DOES accept a const char*, so i solved it with a new Print function, like the afore mentioned.


Er... you wrote cFont:rint(), yes? As long as you don't actually *do modification to the string within Print()* (and you shouldn't), you can just change your function prototype so that it takes const char * instead, and all is well. Keep using the same type the whole way along yeah? Although actually, doing the conversion within Print, and having it take std::string, is better. Good for you for following through on that.

Once-and-only-once'ing takes some practice, a keen eye for similarity, and a disgust for code bloat. It's not as hard as you might think


[edited by - Zahlman on January 27, 2004 6:17:27 AM]
cFont:: Print. Apparently ": P" (no space) is a smilie...
I could''ve changed the Print''s first variable from char* to const char*, but i don''t know where else i''m also using it and actually feeding it a char*, which would then probably complain because char* isn''t a const char*, so to keep things simple i just added another one.

Doesn''t "Once and only once"-ing mean you can never pass by reference? (have one and only one copy of data)

This topic is closed to new replies.

Advertisement