Re: C programmer migrating to C++
Bartosz Wiklak wrote:
In C I used pointers extensively. When I didn't want to overload
function's definition I used function's default NULL arguments to
indicate that this argument (and part of function's job) is not
relevant. I know this could be considered unsafe but imagine several
function calls inside of such function that also use NULL pointer. It
saves much work. In STL there are some values that represent bad or
boundary values such as string::npos or the one returned by iterator
end() method ( btw, it's irritating that every container has different
past-the-end element). Can I achieve something like default NULL
argument in C++ not using pointers but references?
No, actually pointers are a pretty good way to signal that a parameter is
optional. In fact I'd even say that if a parameter is a pointer, then the
parameter is implicitly optional. The only exception I would say is a
pointer to a char or wchar_t.
BTW: The different past-the-end-values for containers are necessary. Imagine
an iterator over an array. Normally, you would only need a pointer, but
suddenly that iterator would also have to know its position inside the
array in order to make the transition between the values inside to the
past-the-end value. IOW, it would suddenly have to know the end of the
sequence, doubling its size and increasing the complexity of its use. The
spirit of the STL in that aspect is to provide sharp tools - a good
craftsman can use them efficiently, a bad craftsman can easily hurt
themselves.
Suppose I want to have a method that returns a "large" object, let it
be a "comp.lang.c++.moderated" string.
I can do it this way:
string& foo( string& buf ){ buf="comp.lang.c++.moderated"; return
buf; }
Note: Assignment typically yields a non-const reference to the left side, so
you could have written
return buf="EHLO WRLD.";
but I need do such things in my code:
string s;
foo(s);
I would like to do sth. like this:
string s = foo();
If I define foo function like that:
string foo(){ string buf="comp.lang.c++.moderated"; return buf; }
I'll work but as far as I understand it'll run several constructors
and copy constructors and I would like to make such operation work as
fast as [ string s("comp.lang.c++.moderated"); ]
I wouldn't worry. Firstly, compilers are pretty good at figuring out that
the string created in foo() is also the one returned, so they will
construct the string already in the right position for passing it back as
returnvalue, which saves one copy. Further, if you initialise the string
with the returnvalue of the function(), as opposed to creating and then
assigning it, the compiler is also usually smart enough to avoid making
another copy.
If you profile and see that you spend too much time doing the function call
and return, there are a few alternatives:
1. Pass in a reference. This is a quick fix, as it requires little changes
to surrounding code, but the code looks a bit ugly.
2. Pass out a pointer to a dynamically allocated object. The problem here is
that it requires a dynamic allocation, which in and of itself takes some
time. Of course the pointer should not be a raw pointer but a smart
pointer, e.g. std::auto_ptr. Note that std::auto_ptr behaves a bit strange
though, make sure you read and understand its semantics! Note that if you
don't want to store and use a pointer, you can swap its pointee with a
local variable:
string x;
auto_ptr<string> p = foo();
x.swap(*p);
4. The upcoming C++ standard offers "move semantics" but isn't universally
implemented yet. I also know too little about it to comment on that.
BTW, is [ string s("comp.lang.c++.moderated"); ] faster than [ string
s ="comp.lang.c++.moderated"; ] or maybe it is compiler dependent?
Both are generally equally fast.
Uli
--
Sator Laser GmbH
Gesch??ftsf??hrer: Thorsten F??cking, Amtsgericht Hamburg HR B62 932
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]