<xl***************@gmail.comwrote:
I have a question about an example presented in the book "INFORMIT C++
Reference Guide" by Danny Kalev:
string getmagicword()
(
return string("Supercalifragilisticexpialidocious");
);
Ummm, no. Perhaps what you mean is:
std::string getmagicword()
{
return string("Supercalifragilisticexpialidocious");
}
Dumb function, though. I'd do this instead:
#define MAGIC_WORD std::string("Supercalifragilisticexpialidocious")
or perhaps this:
const std::string magic_word ("Supercalifragilisticexpialidocious");
Either way saves time and reduces stack usage during runtime.
string magicw=getmagicword();
"getmagicword() constructs a local string object. Next, this local
object is copy-constructed on the caller's stack, making a temporary
string object that is used as the argument of magicw's assignment
operator/copy-constructor. Next, magicw's copy constructor executes, at
last.
Yes, you heard me right: to initialize magicw, it takes no less than:
One constructor call for the local object inside getmagicword().
Two copy constructor calls: one for copying the local object onto the
caller's stack frame, and then another call for copying that copy to
magicw.
I think it's likely a good compiler would elide some of those
constructor calls. But keep in mind that you ARE using copy
semantics here. If you don't want copies, don't use copy
semantics; pass by ref instead. (More on this below.)
Two destructor calls: one for the object created inside getmagicword
and one for the temp copied onto the caller's stack frame."
Now, my question is: Would the same thing happen (a temporary being
created) if you passed an object to the function:
void getmagicword(string object)
(
);
Huh? Do you mean:
void getmagicword(string object)
{
object = std::string("Bob");
}
If so, that won't work. You're still using copy semantics.
Altering object won't alter the argument.
int main()
{
std::string x = "Fred";
getmagicword(x); // Does NOTHING.
std::cout << x << std::endl; // prints "Fred", not "Bob".
return 0;
}
string x;
getmagicword(x); // first example
getmagicword(string()); second example
/* In applying the same principal that the book showed for returning
objects, I came up with the following for passing objects to functions:
*/
/* first example calls constructor, then creates temporary object (out
of local object) on the caller's stack which calls the copy
constructor, then it calls the copy constructor again to initialize the
functions argument with the temporary - Yes?*/
Something close to that, yes. Maybe fewer constructor calls than
you think. Others here could give you more technical details.
Dumb way to go about it, in any case.
/* second example calls constructor, that creates and returns a
temporary object, then calls the copy constructor to create another
temporary object on the caller's stack and initializes it with the
first temporary object, then it calls the copy constructor again to
initialize the functions argument with the last temporary object. -
Yes? */
No. Second example doesn't alter argument at all. (See above.)
If this is different from returning an object
You're not returning an object. Return is "void", remember?
in that a temporary is not created, then why the double standard?
How is the passed in object initialized to the actual argument
in the function definition
When passing by value, altering a parameter does not alter its
argument. (See above.)
(without optimizations of course)?
Optimization has nothing to do with it.
If you need to pass a string into a function which will alter
it, pass the argument by non-constant reference, like this:
void LoadString (std::string & Text)
{
Text = std::string("Bob");
}
int main()
{
std::string Fizzbin ("Fred"); // Loads "Fred" into Fizzbin
LoadString(Fizzbin); // loads "Bob" into Fizzbin
std::cout << Fizzbin << std::endl; // prints "Bob", not "Fred"
return 0;
}
To pass a string (or anything else) to a function that WON'T
alter it, pass the argument by constant reference to reduce
time and RAM wasted making unnecessary copies of things:
double MyQuad(double const & num) // num is alias for argument
{
// Note: num is NOT a local variable here! It's an alias
// to the argument passed to MyQuad. In the case of
// the function call in main() below, num is an alias to
// the variable Tom.
return 3.87*num*num - 17.3*num + 4.57; // return quadratic
}
int main()
{
double Tom = 18.2;
std::cout << MyQuad(Tom) << std::endl; // print quadratic
return 0;
}
(In practice, I'd use a functor for MyQuad, passing-in the
coefficients by parameterized constructor... but I digress.)
--
Cheers,
Robbie Hatley
East Tustin, CA, USA
lone wolf intj at pac bell dot net
(put "[usenet]" in subject to bypass spam filter)
http://home.pacbell.net/earnur/