Phlip wrote:
[color=blue]
> Rich Grise wrote:
>[color=green]
>> I think I've finally found a tutorial that can get me started:
>>
>>
http://www.zib.de/Visual/people/muel.../tutorial.html[/color]
>
> Have you written a "hello world" program yet? And always learn C++ from
> more than two tutorials, at the same time. Try /Accelerated C++/ by Koenig
> and Moo.[/color]
I've copied and pasted one, yes. :-) But this is just the first tutorial
I've checked - I've essentially just started with C++, and figured I should
start with the basics. :-)[color=blue]
>[color=green]
>> So, I see this in the tutorial, which is a construct I've seen in
>> the NG (he's talking about linked lists):
>> --------------
>> list_handle_t<Apple> list1; /* a list of apples */
>> list_handle_t<Car> list2; /* a list of cars */
>> --------------
>> So far, he's been using pseudocode, fair enough, I first learned to
>> copy-n-paste C hundreds of years ago. But I wonder - in this particular
>> example, is this guy speaking "real C++"?[/color]
>
> Unfortunately, yes. They are templates. (But the comments could use //
> instead of /* */.)
>
> The following dissertation intends to help people read C++, not write new
> code. You would do me a major favor if you read the following and told me
> where (if anywhere) you get lost.[/color]
OK:
[color=blue]
> Bjarne Stroustrup invented C++ to provide the popular but low-level C
> language with the keywords virtual, template and operator. Those enable
> Object Oriented techniques with minimal runtime overhead. C is "portable
> assembler", and C++ is "portable OO assembler".
>
> C++ in a Nutshell
> C++ is a statically typed language. It has no latent "Object" base class
> to supply default behaviors to all objects. C++ supports Object Oriented
> techniques, but not everything in C++ is an object.
>
> All C++ entities have a declaration and a definition. C++ uses a compiling
> and linking system that compiles many declarations and a few definitions
> together into one "object code file". Then many of these link together to
> form a complete program.
>
> Only source statements compiled below a declaration can use its
> identifiers. Developers can declare and define classes and functions[/color]
This is the first mention of "function. Does it mean the same as in C?
[color=blue]
> simultaneously (the preferred way), or they can move declarations to
> separate files.[/color]
Would this be as simple as taking the #includes and stuff and putting
them in a header file?
Declarations and definitions aren't too much different from what they
mean in C, are they?
[color=blue]
> This Case Study will show tests followed by the code that
> passes them, but that code, or its declarations, must in source appear
> above their tests.
>
> C++ supports very large Object Oriented applications when modules
> typesafely compile remote modules' interface declarations, without the
> burden of recompiling their implementation definitions.[/color]
OK, I know what each of these words means, but I'm going to have to mull
over this particular permutation for awhile. :-)
But this dissertation is exactly what I'm looking for - I'm really going
to mull, and mark your post as unread, and read the rest after I grasp the
paragraph above. (or at least read more - no guarantees yet!)
Thanks very much!
Rich[color=blue]
>
> Language Law: C++ supports both methods and modules, but has no single
> explicit keyword for either. Programmers assemble methods and modules from
> primitive facilities. Roughly speaking, a method is a virtual class member
> function, and a module is a translation unit, typically based on compiling
> one .cpp file.
>
> The command to import a module's declarations is #include, and the command
> to import an identifier from that module is using. The Hello World project
> for C++ is:
>
> #include <iostream> // copy in declarations, and some definitions
>
> using std::cout; // meaning Console OUTput
> using std::endl; // meaning END of Line
>
> int main()
> {
> cout << "Hello World!" << endl;
> return 0;
> }
>
> The function main() returns a 0, which tells the environment that this
> program ran without errors.
>
> The number 0 has a weak type, usually integer. All C++ functions declare
> their return type, or they declare void to return nothing.
>
> In my Uncommon Style Guide, functions' return types are less important
> than the functions' names. Indenting the return values, like this...
>
> int
> main()
> {
> ...
> }
>
> ...cleans the left column, so scanning it reveals only function names.
> This style becomes very easy to read - especially as function types get
> long.
>
> Applying the Object Method Refactor to the Hello World application yields
> this class:
>
> using std::ostream;
>
> class
> WorldGreeter
> {
> public:
>
> void
> greet(ostream &out)
> {
> out << "Hello World!" << endl;
> }
> };
>
> int
> main()
> {
> WorldGreeter aGreeter;
> aGreeter.greet(cout);
> return 0;
> }
>
> The console stream object, cout, passes into greet() by reference. greet()
> takes a reference (&) to an ostream, which is one of cout's classes' base
> classes. ostream and many classes derived from it use << to insert data
> into their streams.
>
> This stream insertion concept makes the following chapters easier to
> understand. C++ permits operator overloading, meaning programmers specify
> what some operators do. The operator <<, applied to integers, shifts their
> bits, so 2 << 3 == 16.
>
> Shifting objects makes no sense, so << is free to overload for stream
> objects. Refactoring our "Hello World" project, one more time, illustrates
> this principle:
>
> class
> WorldGreeter
> {
> public:
>
> void
> greet(ostream &out) const
> {
> out << "Hello World!";
> }
> };
>
> ostream &
> operator<<(ostream &out, WorldGreeter const &aGreeter)
> {
> aGreeter.greet(out);
> return out;
> }
>
> int
> main()
> {
> WorldGreeter aGreeter;
> cout << aGreeter << endl;
> return 0;
> }
>
> The ability to insert any object, as text, into a stream, is more than
> syntactic sugar. When templates and macros call operator<<, they can use
> any argument type that has such an operator. The Standard Library defines
> operator<< for all the primitive data types-int, double, std::string,
> etc.-and programmers define one for each object they need. Note the above
> operator<< is part of WorldGreeter's interface, but is not a member of the
> WorldGreeter class. C++ types work in mysterious ways.
>
> In C++, classes are not objects. This makes passing a class into a method,
> as a parameter, problematic. C++ compiles all class details into various
> opcodes, wherever they occur, so a running C++ program has no single
> entity to refer to as a class.
>
> C++ programs use templates to merge types. Each template instantiation
> expands a class-like definition into a set of classes, each varying by
> some type or integer.
>
> This example upgrades our WorldGreeter example one more useless time. This
> version converts WorldGreeter into a template, parameterized by an integer
> that sets how ecstatically the two instantiated classes, WorldGreeter<2>
> and WorldGreeter<3>, greet the world:
>
> template<int count>
> class
> WorldGreeter
> {
> public:
>
> void
> greet(ostream &out) const
> {
> for(int x = 0; x < count; ++x)
> out << "Hello World! ";
> }
> };
>
> ostream &
> operator<<(ostream &out, WorldGreeter<2> const &aGreeter)
> {
> aGreeter.greet(out);
> return out;
> }
>
> ostream &
> operator<<(ostream &out, WorldGreeter<3> const &aGreeter)
> {
> aGreeter.greet(out);
> return out;
> }
>
> int
> main()
> {
> WorldGreeter<2> aGreeter2;
> WorldGreeter<3> aGreeter3;
> cout << aGreeter2 << aGreeter3 << endl;
> return 0;
> }
>
> When templates parameterize based on types, they can create new classes
> that specialize to manage any of a range of details for each type. For
> example, the C++ Standard Library provides a template called
> std::basic_string<>. Supplying this with a character type provides string
> types of any needed width:
>
> namespace std {
> typedef basic_string<char> string; // 8-bits
> typedef basic_string<wchar_t> wstring; // 16-bits
> }
>
> The keyword namespace is one of the language primitives that collude to
> create modules. Identifiers from the C++ Standard Library often begin with
> std::, to distinguish their source module. A namespace is a prefix (std)
> that must precede all uses of identifiers declared within their scope
> (string, wstring). The scope operator, ::, links them.
>
> The keyword typedef converts a type declaration into a single name. Here,
> it instantiates templates into their target classes. The sample creates
> the class std::string, to contain 8-bit character strings, and the class
> std::wstring, to contain 16-bit character strings.
>
> To avoid writing std:: all over the place, insert a namespace's
> identifiers into your scope with a few using declarations:
>
> #include <string>
> #include <sstream>
> #include <iostream>
>
> using std::string;
> using std::stringstream;
> using std::cout; // console output stream
> using std::endl; // line feed object
>
> C++ macros provide some important features above the level of the actual
> language. Here's a macro, using some of those stream things:
>
> #define db(x_) cout << (x_) << endl
>
> Macros perform simple text substitutions directly on raw C++ source,
> before the type-sensitive phase of compilation. Put another way, if you
> can't think how to do something directly, you can often write a macro to
> do it. (Those of you who know C++ well enough to abhor that advice are
> requested to attempt the following techniques using any other C++
> facilities.)
>
> Below that macro, if you write db(5), you get cout << (5) << endl. A rote
> text substitution, without awareness of 5's meaning. It's just raw text.
> The cout << (5) then inserts 5, typesafely, into the console stream, so
> you can see it on a command prompt. The << endl part delivers a linefeed,
> and flushes that console stream's buffer.
>
> So far, a small templated function could have performed the same feat. Use
> macros for the stringerizer operator, #:
>
> #define db(x_) cout << #x_ ": " << (x_) << endl
>
> "db" stands for debug. If q == 5, and if q is suspicious, we can trace q's
> name and value to the console using db(q). That outputs "q: 5\n". This
> macro makes our trace statement easy to write. The equivalent printf()
> statement (if q were only an integer) would be printf("q: %i\n", q). Our
> statement works for any type that supports an operator<<, and it outputs
> the name of q automatically, using #x_.
>
> Suppose a long program run emitted a strange message, complaining about
> some obscure variable named q. Rapidly finding the line of code containing
> that db(q) call relieves stress:
>
> #define db(x_) do { \
> cout << __FILE__ << "(" << __LINE__ << ") : " \
> #x_ " = " << x_ << endl; } while (false)
>
> That emits, roughly, "C:\path\source.cpp(99) : q = 5\n". All from one
> easily written db(q) call.
>
> The do and while(false) keywords force the statement containing db(q) to
> finish with a healthy ; semicolon. Macros need techniques, like extra
> parentheses, to avoid clashing with raw C++ statements.
>
> On the ends of broken lines, two reverse solidi, \, join everything into
> one long macro. The __FILE__ and __LINE__ symbols are magic constants,
> defined by the C languages, which expand into the current name of the
> source file and line number.
>
> When a program encounters syntax errors, faults, or trace statements, the
> same keystroke must navigate to any of them.
>
> Visual Studio surfs to errors using <F8>: Go To Output Window Next
> Location. The Windows SDK function to write text into the output panel,
> for this feature to read it and surf to an error, is OutputDebugString().
> Putting them all together yields this killer trace macro:
>
> #define db(x_) do { std::stringstream z; \
> z << __FILE__ << "(" << __LINE__ << ") : " \
> #x_ " = " << x_ << endl; \
> cout << z.str() << std::flush; \
> OutputDebugStringA(z.str().c_str()); \
> } while (false)
>
> That takes any argument, including expressions, which support operator<<.
> We will return to these techniques while exploring more Fault Navigation
> issues in C++.
>
> db(q) pushes "C:\path\source.cpp(99) : q = 5\n" into the Output Debug
> panel. <F8> parses the file name and line number and navigates your editor
> directly to the line containing the db(q).
>
> Those are major wins. Tracing with db() is very low cost for very high
> feedback.
>
> C++ has flaws. But those of you inclined to dismiss it entirely are
> invited to write db(), with all these features, in your favorite language.
>[/color]