String Reference from String Literal C++
I'm hoping someone can help answer a question about strings in C++. I've tried to strip out any extraneous code from here, so it wont compile (missing namespace, defines, etc...). This is not a "bug" problem. If working code samples are needed, please specify what code you would like (for which question), I'd be happy to put something more detailed up.
//Foo.c
#define EXIT "exit"
Bar* bar; //See question C
//1
foo(const string& text) {
cout << text;
bar = new Bar(text); //See question C
}
//2
foo(const char* text) {
cout << text;
}
//3
foo(string text) {
cout << text;
}
int main() {
....
{ foo(EXIT); } //braces for scope, see question C)
bar->print(); //4
....
}
class Bar {
private const string& strBar;
Bar::Bar(const string& txt) : strBar(txt) { }
Bar::print() { cout << strBar; }
}
Assuming that only one of the three foo() methods is uncommented, they are not meant to be overloaded. I have a couple of questions here:
A) If I could figure out how to use OllyDbg well enough to fiddle the string literal "exit" into "axit" AFTER the call foo() is made, I believe the output would still be "exit" in case 1 and 3, and开发者_开发问答 "exit" in case 2. Is this correct?
B) In case 1 and 3, I believe that because the method is asking for a String (even if it is a reference in case 1), there is an implicit call to the string constructor (it accepts const char*), and that constructor ALWAYS makes a copy, never a reference. (see cplusplus.com string page ) Is this correct (especially the ALWAYS)?
C) In case 1, if I initialised a new class which had a string& attribute to which I assigned the text variable, will this reference wind up pointing to bad memory when we leave the scope? IE, when we reach 4, I believe the following has happened (assuming foo(const string& text) is the uncommented function): 1. A temporary string object is create for the line foo(EXIT) that copies the literal. 2. The reference to the temp object is passed through to bar and to the strBar attribute 3. Once the code moves on and leaves the scope in which foo(EXIT) was called, I believe that the temp string object goes out of scope and disappears, which means strBar now references an area of memory with undefined contents, thinking it is still a string.
D) Going back to A, I believe in case 2 (foo(const char* text)) that this call to foo references the literal itself, not a copy, which is why fiddling with the literal in memory would change the output. Is this correct? Could I continue to pass the literal through (say to Bar) if I continued to use const char*?
E) How would you go about testing any of this beyond "this is how it works"? and "read the specs"? I don't need step by step instructions, but some ideas on what I should have done to answer the question myself using the tools I have available (Visual Studio, OllyDbg, suggestions for others?) would be great. I've spent a goodly amount of time trying to do it, and I'd like to hear what people have to say.
A) I don't know anything about OllyDbg
, but in all cases std::ostream
makes it's own copy of text
before foo
returns, so any changing of the variables after the call will not affect the output.
B) Yes, the string
constructor will always make it's own copy of a char*
during the implicit construction for the parameter.
C) Yes, when you call foo
, a string
is automatically created and used, and after the call ends, it is destroyed, leaving bar
pointing at invalid memory.
D) You are correct. foo(const char* text)
makes a copy of the pointer to the data, but does not copy the data. But since operator<<(ostream, char*)
makes a copy of the data, changing the data will not affect the output. I don't see why you couldn't pass the const char*
literal through.
E) Take a class, read a tutorial, or read the specs. Trial and error won't get you far in the standard library for this sort of question.
For these, the concept is encapsulation. The objects in the C++ standard library are all encapsulated, so that the results of any operation are what you would expect, and it is really hard to accidentally mess with their internals to make things fail or leak. If you tell ostream
to print the data at a char *
, it will (A) do it immediately, or (B) make it's own copy before it returns in case you mess with the char*
later.
精彩评论