> explain what the colon in these lines/constructs do (I'm still learning C++):
>
struct C { C( int i = 6 ) : v(i) {} int v ; /* .... */ };
>
A() : c(20) {}
The respective constructors are using
member initializer lists t initialize the members.
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr388.htm
Line 19 in the first snippet
int i = 234 ;
is an in-class member initializer.
http://www.stroustrup.com/C++11FAQ.html#member-init
> Finally, why is the following statement needed?
>
using C::C ; // inherit constructors
In
struct sub_object_C : C
, we want
sub_object_C
to be usable exactly like a
C
; we want it to be constructible exactly like a
C
; and inherited constructors provide a succinct way of saying that 'an object of this derived class can be constructed using the syntax and semantics of any of the constructors present in the base class'
http://www.stroustrup.com/C++11FAQ.html#inheriting
> I do not fully understand the codes you provided: especially the second solution
The C++ stream library is an extremely flexible library; primarily this flexibility comes from separation of different concerns into different components, with the facility to mix and match these components as required.
Every stream has an associated stream buffer; the stream buffer is responsible for in-memory buffering of characters that are input/output, and transporting these characters from/to an actual physical target like a file. We can replace the stream buffer associated with a stream with another stream buffer when we want to redirect output elsewhere.
http://www.cplusplus.com/reference/ios/ios/rdbuf/
std::cout
is an output stream, by default it is associated with a custom stream buffer that sends the output characters to stdout.
std::stringbuf
is another kind of stream buffer; it sends the output characters to a string held in memory.
http://www.cplusplus.com/reference/sstream/stringbuf/
(Needless to say,
std::filebuf
is yet another kind of stream buffer which sends the output to a file.)
What we are doing is:
a. replace the stream buffer associated with
std::cout
with a
std::stringbu
f
b. save the original stream buffer (we want to restore it at the end)
c. call the function(s) which perform output with
std::cout
d. the actual output to
std::cout
is written via the
std::stringbuf
e. copy that output from the stringbuf into a string of out own
f. finally, restore the original stream buffer asociated with
std::cout
.
Things get messy if an exception is thrown, somewhere in between steps a. and f.; we are C++ programmers, so we use RAII. We wrap the whole sequence to between the constructor and the destructor of the shim class
redirect_to_string
, and our code automagically becomes exception safe.
Streambuf tutorial:
http://www.mr-edd.co.uk/blog/beginners_guide_streambuf