├── LICENSE ├── Makefile ├── README.html ├── README.rst ├── exam.html ├── exam.rst ├── exam ├── Makefile ├── exam-1 ├── exam-1.cc ├── exam-10 ├── exam-10.cc ├── exam-2 ├── exam-2.cc ├── exam-3 ├── exam-3.cc ├── exam-4 ├── exam-4.cc ├── exam-5 ├── exam-5.cc ├── exam-6 ├── exam-6.cc ├── exam-7 ├── exam-7.cc ├── exam-8 ├── exam-8.cc ├── exam-9 └── exam-9.cc ├── page.tmpl ├── pygment.css ├── rst2html.py ├── sources ├── .DS_Store ├── Makefile ├── crash-course-2.1.cc ├── crash-course-2.2.cc ├── crash-course-2.3.cc ├── crash-course-2.4.cc ├── crash-course-2.5.cc ├── crash-course-2.6.cc ├── crash-course-3.1.cc ├── crash-course-3.2.cc ├── crash-course-3.3.cc ├── crash-course-3.4.cc ├── crash-course-3.5.cc ├── crash-course-4.1.cc ├── crash-course-4.2.cc ├── crash-course-4.3.cc ├── crash-course-4.4.cc ├── crash-course-4.5.cc ├── crash-course-5.1.cc ├── crash-course-5.2.cc ├── crash-course-5.3.cc └── crash-course-5.4.cc └── stylesheet.css /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Nicolas P. Rougier 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | MAKE = /usr/bin/make 2 | RST2HTML = ./rst2html.py 3 | STYLESHEET = stylesheet.css 4 | RST2HTML_OPTIONS = --strip-comments \ 5 | --report=3 \ 6 | --section-numbering \ 7 | --no-toc-backlinks \ 8 | --template=page.tmpl \ 9 | --cloak-email-addresses \ 10 | --stylesheet=$(STYLESHEET) \ 11 | --link-stylesheet 12 | 13 | SOURCES = $(wildcard *.rst) 14 | OBJECTS = $(subst .rst,.html, $(SOURCES)) 15 | 16 | all: $(OBJECTS) pygment.css 17 | 18 | #pygment.css: 19 | # @pygmentize -S tango -f html > pygment.css 20 | 21 | %.html: %.rst Makefile 22 | @echo " - $@" 23 | @$(RST2HTML) $(RST2HTML_OPTIONS) $< $@ 24 | 25 | clean: 26 | @-rm -f $(OBJECTS) 27 | 28 | distclean: clean 29 | @-rm -f `find . -name "*~"` 30 | 31 | .PHONY: all home clean distclean 32 | -------------------------------------------------------------------------------- /README.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | C++ crash course for C programmers 8 | 9 | 10 | 11 | 12 |
13 |

C++ crash course for C programmers

14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
Author:Nicolas P. Rougier
Sources:crash-course.rst
24 |
25 | 90 |
91 |
92 |

1   Foreword

93 |

This is an introduction to C++ for C programmers:

94 | 126 |
127 |
128 |

2   From C to C++

129 |

Even if C++ is slanted toward object-oriented programming (OOP), you can 130 | nevertheless use any c++ compiler to compile c code and benefits from some c++ 131 | goodies.

132 |
133 |

2.1   Input/Output

134 |

Prefer the use of <iostream> for input/output operations (see stream 135 | section for explanation).

136 |
 137 | #include <iostream>
 138 | 
 139 | int main (int argc, char **argv)
 140 | {
 141 |     int i;
 142 |     std::cout << "Please enter an integer value: ";
 143 |     std::cin >> i;
 144 |     std::cout << "The value you entered is " << i  << std::endl;
 145 |     return 0;
 146 | }
 147 | 
148 |
149 |
150 |

2.2   New/Delete

151 |

The new and delete keywords are used to allocate and free memory. They 152 | are "object-aware" so you'd better use them instead of malloc and 153 | free. In any case, never cross the streams (new/free or malloc/delete).

154 |
 155 | int *a = new int;
 156 | delete a;
 157 | 
 158 | int *b = new int[5];
 159 | delete [] b;
 160 | 
161 |

delete does two things: it calls the destructor and it deallocates the 162 | memory.

163 |
164 |
165 |

2.3   References

166 |

A reference allows to declare an alias to another variable. As long as the 167 | aliased variable lives, you can use indifferently the variable or the alias.

168 |
 169 | int x;
 170 | int& foo = x;
 171 | 
 172 | foo = 42;
 173 | std::cout << x << std::endl;
 174 | 
175 |

References are extremely useful when used with function arguments since it 176 | saves the cost of copying parameters into the stack when calling the function.

177 |
178 |
179 |

2.4   Default parameters

180 |

You can specify default values for function parameters. When the function is 181 | called with fewer parameters, default values are used.

182 |
 183 | float foo( float a=0, float b=1, float c=2 )
 184 | {return a+b+c;}
 185 | 
 186 | cout << foo(1) << endl
 187 |      << foo(1,2) << endl
 188 |      << foo(1,2,3) << endl;
 189 | 
190 |

You should obtain values 4, 5 and 6.

191 |
192 |
193 |

2.5   Namespaces

194 |

Namespace allows to group classes, functions and variable under a common scope 195 | name that can be referenced elsewhere.

196 |
 197 | namespace first  { int var = 5; }
 198 | namespace second { int var = 3; }
 199 | cout << first::var << endl << second::var << endl;
 200 | 
201 |

You should obtain values 3 and 5. There exists some standard namespace in the 202 | standard template library such as std.

203 |
204 |
205 |

2.6   Overloading

206 |

Function overloading refers to the possibility of creating multiple functions 207 | with the same name as long as they have different parameters (type and/or 208 | number).

209 |
 210 | float add( float a, float b )
 211 | {return a+b;}
 212 | 
 213 | int add( int a, int b )
 214 | {return a+b;}
 215 | 
216 |

It is not legal to overload a function based on the return type (but you can do it 217 | anyway)

218 |
219 |
220 |

2.7   Const & inline

221 |

Defines and macros are bad if not used properly as illustrated below

222 |
 223 | #define SQUARE(x) x*x
 224 | 
 225 | int result = SQUARE(3+3);
 226 | 
227 |

For constants, prefer the const notation:

228 |
 229 | const int two = 2;
 230 | 
231 |

For macros, prefer the inline notation:

232 |
 233 | int inline square(int x)
 234 | {
 235 |     return x*x;
 236 | }
 237 | 
238 |
239 |
240 |

2.8   Mixing C and C++

241 |
 242 | #ifdef __cplusplus
 243 | extern "C" {
 244 | #endif
 245 | 
 246 | #include "some-c-code.h"
 247 | 
 248 | #ifdef __cplusplus
 249 | }
 250 | #endif
 251 | 
 252 | 
253 |
254 |
255 |

2.9   Exercises

256 |
    257 |
  1. Write a basic makefile for compiling sources

    258 |

    solution: Makefile

    259 |
  2. 260 |
  3. How would you declare:

    261 |
  4. 262 |
263 |
264 |
    265 |
  • A pointer to a char
  • 266 |
  • A constant pointer to a char
  • 267 |
  • A pointer to a constant char
  • 268 |
  • A constant pointer to a constant char
  • 269 |
  • A reference to a char
  • 270 |
  • A reference to a constant char
  • 271 |
272 |

solution: crash-course-2.1.cc

273 |
274 |
    275 |
  1. Create a two-dimensional array of integers (size is n x n), fill it with 276 | corresponding indices (a[i][j] = i*n+j), test it and finally, delete it.
  2. 277 |
278 |
279 | solution: crash-course-2.2.cc
280 |
    281 |
  1. Write a function that swap two integers, then two pointers.
  2. 282 |
283 |
284 | solution: crash-course-2.3.cc
285 |
    286 |
  1. Is this legal ?

    287 |
     288 | int add( int a, int b ) { return a+b; }
     289 | 
     290 | int add( int a, int b, int c=0 ) { return a+b+c; }
     291 | 
    292 |
  2. 293 |
294 |
295 | solution: crash-course-2.4.cc
296 |
    297 |
  1. Write a const correct division function.
  2. 298 |
299 |
300 | solution: crash-course-2.5.cc
301 |
    302 |
  1. What's the difference between int const* p, int* const p 303 | and int const* const p ?
  2. 304 |
305 |
306 | solution: crash-course-2.6.cc
307 |
308 |
309 |
310 |

3   Classes

311 |

A class migh be considered as an extended concept of a data structure: instead 312 | of holding only data, it can hold both data and functions. An object is an 313 | instantiation of a class. By default, all attributes and functions of a class 314 | are private (see below Access control). If you want a public default behavior, 315 | you can use keyword struct instead of keyword class in the declaration.

316 |
 317 | class Foo {
 318 |     int attribute;
 319 |     int function( void ) { };
 320 | };
 321 | 
 322 | struct Bar {
 323 |     int attribute;
 324 |     int function( void ) { };
 325 | };
 326 | 
 327 | Foo foo;
 328 | foo.attribute = 1; // WRONG
 329 | 
 330 | Bar bar;
 331 | bar.attribute = 1;  // OK
 332 | 
 333 | 
334 |
335 |

3.1   Constructors

336 |

It is possible to specify zero, one or more constructors for the class.

337 |
 338 | #include <iostream>
 339 | 
 340 | class Foo {
 341 | public:
 342 |     Foo( void )
 343 |     { std::cout << "Foo constructor 1 called" << std::endl; }
 344 |     Foo( int value )
 345 |     { std::cout << "Foo constructor 2 called" << std::endl; }
 346 | };
 347 | 
 348 | int main( int argc, char **argv )
 349 | {
 350 |     Foo foo_1, foo_2(2);
 351 |     return 0;
 352 | }
 353 | 
354 |
355 |
356 |

3.2   Destructor

357 |

There can be only one destructor per class. It takes no argument and returns 358 | nothing.

359 |
 360 | #include <iostream>
 361 | 
 362 | class Foo {
 363 | public:
 364 |     ~Foo( void )
 365 |     { std::cout << "Foo destructor called" << std::endl; }
 366 | }
 367 | int main( int argc, char **argv )
 368 | {
 369 |     Foo foo();
 370 |     return 0;
 371 | }
 372 | 
373 |

Note that you generally never need to explicitly call a destructor.

374 |
375 |
376 |

3.3   Access control

377 |

You can have fine control over who is granted access to a class function or 378 | attribute by specifying an explicit access policy:

379 |
    380 |
  • public: Anyone is granted access
  • 381 |
  • protected: Only derived classes are granted access
  • 382 |
  • private: No one but friends are granted access
  • 383 |
384 |
385 |
386 |

3.4   Initialization list

387 |

Object's member should be initialized using initialization lists

388 |
 389 | class Foo
 390 | {
 391 |     int _value;
 392 | public:
 393 |     Foo(int value=0) : _value(value) { };
 394 | };
 395 | 
396 |

It's cheaper, better and faster.

397 |
398 |
399 |

3.5   Operator overloading

400 |
 401 | class Foo {
 402 | private:
 403 |     int _value;
 404 | 
 405 | public:
 406 |     Foo( int value ) : _value(value) { };
 407 | 
 408 |     Foo operator+ ( const Foo & other )
 409 |     {
 410 |         return Foo( _value+ other._value );
 411 |     }
 412 | 
 413 |     Foo operator* ( const Foo & other );
 414 |     {
 415 |         return Foo( _value * other._value );
 416 |     }
 417 | }
 418 | 
419 |
420 |
421 |

3.6   Friends

422 |

Friends are either functions or other classes that are granted privileged 423 | access to a class.

424 |
 425 | #include <iostream>
 426 | 
 427 | class Foo {
 428 | public:
 429 |     friend std::ostream& operator<< ( std::ostream& output,
 430 |                                       Foo const & that )
 431 |     {
 432 |         return output << that._value;
 433 |     }
 434 | private:
 435 |     double _value;
 436 | };
 437 | 
 438 | int main( int argc, char **argv )
 439 | {
 440 |   Foo foo;
 441 |   std::cout << "Foo object: " << foo << std::endl;
 442 |   return 0
 443 | }
 444 | 
445 |
446 |
447 |

3.7   Exercices

448 |
    449 |
  1. Why the following code doesn't compile ?

    450 |
     451 | class Foo { Foo () { }; };
     452 | 
     453 | int main( int argc, char **argv )
     454 | {
     455 |     Foo foo;
     456 | }
     457 | 
    458 |

    solution: crash-course-3.1.cc

    459 |
  2. 460 |
  3. Write a Foo class with default and copy constructors and add also an 461 | assignment operator. Write some code to highlight the use of each of them.

    462 |

    solution: crash-course-3.2.cc

    463 |
  4. 464 |
  5. Write a Point class that can be constructed using cartesian or polar 465 | coordinates.

    466 |

    solution: crash-course-3.3.cc

    467 |
  6. 468 |
  7. Write a Foo class and provide it with an input method.

    469 |

    solution: crash-course-3.4.cc

    470 |
  8. 471 |
  9. Is is possible to write something like foo.method1().method2() ?

    472 |

    solution: crash-course-3.5.cc

    473 |
  10. 474 |
475 |
476 |
477 |
478 |

4   Inheritance

479 |
480 |

4.1   Basics

481 |

Inheritance is done at the class definition level by specifying the base class 482 | and the type of inheritance.

483 |
 484 | class Foo                            { /* ... */ };
 485 | class Bar_public : public Foo        { /* ... */ };
 486 | class Bar_private : private Foo      { /* ... */ };
 487 | class Bar_protected : protected Foo  { /* ... */ };
 488 | 
489 |

Bar_public, Bar_private and Bar_protected are derived from Foo. 490 | Foo is the base class of Bar_public, Bar_private and Bar_protected.

491 |
    492 |
  • In Bar_public, public parts of Foo are public, 493 | protected parts of Foo are protected
  • 494 |
  • In Bar_private, public and protected parts of Foo are private
  • 495 |
  • In Bar_protected, public and protected parts of Foo are protected
  • 496 |
497 |
498 |
499 |

4.2   Virtual methods

500 |

A virtual function allows derived classes to replace the implementation 501 | provided by the base class (yes, it is not automatic...). Non virtual methods 502 | are resolved statically (at compile time) while virtual methods are resolved 503 | dynamically (at run time).

504 |
 505 | class Foo {
 506 | public:
 507 |     Foo( void );
 508 |     void method1( void );
 509 |     virtual void method2( void );
 510 | };
 511 | 
 512 | class Bar : public Foo {
 513 | public:
 514 |     Bar( void );
 515 |     void method1( void );
 516 |     void method2( void );
 517 | };
 518 | 
 519 | Foo *bar = new Bar();
 520 | bar->method1();
 521 | bar->method2();
 522 | 
523 |

Make sure your destructor is virtual when you have derived class.

524 |
525 |
526 |

4.3   Abstract classes

527 |

You can define pure virtual method that prohibits the base object to be 528 | instantiated. Derived classes need then to implement the virtual method.

529 |
 530 | class Foo {
 531 | public:
 532 |     Foo( void );
 533 |     virtual void method( void ) = 0;
 534 | };
 535 | 
 536 | class Bar: public Foo {
 537 | public:
 538 |     Foo( void );
 539 |     void method( void ) { };
 540 | };
 541 | 
542 |
543 |
544 |

4.4   Multiple inheritance

545 |

A class may inherit from multiple base classes but you have to be careful:

546 |
 547 | class Foo               { protected: int data; };
 548 | class Bar1 : public Foo { /* ... */ };
 549 | class Bar2 : public Foo { /* ... */ };
 550 | class Bar3 : public Bar1, public Bar2 {
 551 |     void method( void )
 552 |     {
 553 |        data = 1; // !!! BAD
 554 |     }
 555 | };
 556 | 
557 |

In class Bar3, the data reference is ambiguous since it could refer to 558 | Bar1::data or Bar2::data. This problem is referred as the diamond 559 | problem. You can eliminete the problem by explicitely specifying the data 560 | origin (e.g. Bar1::data) or by using virtual inheritance in Bar1 and Bar2.

561 |
562 |
563 |

4.5   Exercices

564 |
    565 |
  1. Write a Bar class that inherits from a Foo class and makes 566 | constructor and destructor methods to print something when called.

    567 |

    solution: crash-course-4.1.cc

    568 |
  2. 569 |
  3. Write a foo function and make it called from a class that has 570 | a foo method.

    571 |

    solution: crash-course-4.2.cc

    572 |
  4. 573 |
  5. Write a Real base class and a derived Integer class with all common 574 | operators (+,-,*,/)

    575 |

    solution: crash-course-4.3.cc

    576 |
  6. 577 |
  7. Write a Singleton class such that only one object of this class can be 578 | created.

    579 |

    solution: crash-course-4.4.cc

    580 |
  8. 581 |
  9. Write a functor class

    582 |

    solution: crash-course-4.5.cc

    583 |
  10. 584 |
585 |
586 |
587 |
588 |

5   Exceptions

589 |
590 |

5.1   The Zen of Python

591 |

(by Tim Peters)

592 |
593 |
594 |
Beautiful is better than ugly.
595 |
Explicit is better than implicit.
596 |
Simple is better than complex.
597 |
Complex is better than complicated.
598 |
Flat is better than nested.
599 |
Sparse is better than dense.
600 |
Readability counts.
601 |
Special cases aren't special enough to break the rules.
602 |
Although practicality beats purity.
603 |
Errors should never pass silently.
604 |
Unless explicitly silenced.
605 |
In the face of ambiguity, refuse the temptation to guess.
606 |
There should be one-- and preferably only one --obvious way to do it.
607 |
Although that way may not be obvious at first unless you're Dutch.
608 |
Now is better than never.
609 |
Although never is often better than right now.
610 |
If the implementation is hard to explain, it's a bad idea.
611 |
If the implementation is easy to explain, it may be a good idea.
612 |
Namespaces are one honking great idea -- let's do more of those!
613 |
614 |
615 |
616 |
617 |

5.2   Catch me if you can

618 |

You can catch any exception using the following structure:

619 |
 620 | try
 621 | {
 622 |     float *array = new float[-1];
 623 | }
 624 | catch( std::bad_alloc e )
 625 | {
 626 |     std::cerr << e.what() << std::endl;
 627 | }
 628 | 
629 |

If the raised exception is different from the ones you're catching, program 630 | will stop.

631 |
632 |
633 |

5.3   Creating your own exception

634 |

Creating a new exception is quite easy:

635 |
 636 | #include <stdexcept>
 637 | 
 638 | class Exception : public std::runtime_error
 639 | {
 640 | public:
 641 |     Exception() : std::runtime_error("Exception") { };
 642 | };
 643 | 
644 |
645 |
646 |

5.4   Standard exceptions

647 |

There exist some standard exceptions that can be raised in some circumstances:

648 |

#include <stdexcept>

649 |
    650 |
  • bad_alloc
  • 651 |
  • bad_cast
  • 652 |
  • bad_exception
  • 653 |
  • bad_typeid
  • 654 |
  • logic_error
      655 |
    • domain_error
    • 656 |
    • invalid_argument
    • 657 |
    • length_error
    • 658 |
    • out_of_range
    • 659 |
    660 |
  • 661 |
  • runtime_error
      662 |
    • range_error
    • 663 |
    • overflow_error
    • 664 |
    • underflow_error
    • 665 |
    666 |
  • 667 |
668 |
669 |
670 |

5.5   Exercices

671 |
    672 |
  1. How to handle a constructor that fails ?

    673 |

    solution: crash-course-5.1.cc

    674 |
  2. 675 |
  3. Write a program that raise 3 of the standard exceptions.

    676 |

    solution: crash-course-5.2.cc

    677 |
  4. 678 |
  5. Write a correct division function.

    679 |

    solution: crash-course-5.3.cc

    680 |
  6. 681 |
  7. Write a Integer (positive) class with proper exception handling 682 | (Overflow, Underflow, DivideByZero, etc.)

    683 |

    solution: crash-course-5.4.cc

    684 |
  8. 685 |
686 |
687 |
688 |
689 |

6   Streams

690 |

C++ provides input/output capability throught the iostream classes that provide 691 | the stream concept (iXXXstream for input and oXXXstream for output).

692 |
693 |

6.1   iostream and ios

694 |

Screen outputs and keyboard inputs may be handled using the iostream header 695 | file:

696 |
 697 | #include <iostream>
 698 | 
 699 | int main( int argc, char **argv )
 700 | {
 701 | 
 702 |     unsigned char age = 65;
 703 |     std::cout << static_cast<unsigned>(age)     << std::endl;
 704 |     std::cout << static_cast<void const*>(&age) << std::endl;
 705 | 
 706 |     double f = 3.14159;
 707 |     cout.unsetf(ios::floatfield);
 708 |     cout.precision(5);
 709 |     cout << f << endl;
 710 |     cout.precision(10);
 711 |     cout << f << endl;
 712 |     cout.setf(ios::fixed,ios::floatfield);
 713 |     cout << f << endl;
 714 | 
 715 |     std::cout << "Enter a number, or -1 to quit: ";
 716 |     int i = 0;
 717 |     while( std::cin >> i )
 718 |     {
 719 |         if (i == -1) break;
 720 |         std::cout << "You entered " << i << '\n';
 721 |     }
 722 |     return 0;
 723 | }
 724 | 
725 |
726 |
727 |

6.2   Class input/output

728 |

You can implement a class input and output using friends functions:

729 |
 730 | #include <iostream>
 731 | 
 732 | class Foo {
 733 | public:
 734 |     friend std::ostream& operator<< ( std::ostream & output, Foo const & that )
 735 |     { return output << that._value; }
 736 |     friend std::istream& operator>> ( std::istream & input, Foo& foo )
 737 |     { return input >> fred._value; }
 738 | 
 739 | private:
 740 |     double _value;
 741 | };
 742 | 
743 |
744 |
745 |

6.3   Working with files

746 |
 747 | #include <fstream>
 748 | 
 749 | int main( int argc, char **argv )
 750 | {
 751 |     std::ifstream input( filename );
 752 |     // std::ifstream input( filename, std::ios::in | std::ios::binary);
 753 | 
 754 |     std::ofstream output( filename );
 755 |     // std::ofstream output( filename, std::ios::out | std::ios::binary);
 756 | 
 757 |     return 0;
 758 | }
 759 | 
760 |
761 |
762 |

6.4   Working with strings

763 |
 764 | #include <sstream>
 765 | 
 766 | int main( int argc, char **argv )
 767 | {
 768 |     const char *svalue = "42.0";
 769 |     int ivalue;
 770 |     std::istringstream istream;
 771 |     std::ostringstream ostream;
 772 | 
 773 |     istream.str(svalue);
 774 |     istream >> ivalue;
 775 |     std::cout << svalue << " = " << ivalue << std::endl;
 776 | 
 777 |     ostream.clear();
 778 |     ostream << ivalue;
 779 |     std::cout << ivalue << " = " << ostream.str() << std::endl;
 780 | 
 781 |     return 0;
 782 | }
 783 | 
784 |
785 |
786 |

6.5   Exercices

787 |
    788 |
  1. Write an itoa and an atoi function
  2. 789 |
  3. Write a foo class with some attributes and write functions for writing to 790 | file and reading from file.
  4. 791 |
792 |
793 |
794 |
795 |

7   Templates

796 |

Templates are special operators that specify that a class or a function is 797 | written for one or several generic types that are not yet known. The format for 798 | declaring function templates is:

799 | 803 |

You can have several templates and to actually use a class or function 804 | template, you have to specify all unknown types:

805 |
 806 | template<typename T1>
 807 | T1 foo1( void ) { /* ... */ };
 808 | 
 809 | template<typename T1, typename T2>
 810 | T1 foo2( void ) { /* ... */ };
 811 | 
 812 | template<typename T1>
 813 | class Foo3 { /* ... */ };
 814 | 
 815 | 
 816 | int a = foo1<int>();
 817 | float b = foo2<int,float>();
 818 | Foo<int> c;
 819 | 
820 |
821 |

7.1   Template parameters

822 |

There are three possible template types:

823 |
    824 |
  • Type

    825 |
    826 |
     827 | template<typename T>  T foo( void ) { /* ... */ };
     828 | 
    829 |
    830 |
  • 831 |
  • Non-type

    832 |
    833 |
     834 | template<int N>  foo( void ) { /* ... */ };
     835 | 
    836 |
    837 |
  • 838 |
  • Template

    839 |
    840 |
     841 | template< template <typename T> > foo( void ) { /* ... */ };
     842 | 
    843 |
    844 |
  • 845 |
846 |
847 |
848 |

7.2   Template function

849 |
 850 | template <class T>
 851 | T max( T a, T b)
 852 | {
 853 |     return( a > b ? a : b );
 854 | }
 855 | 
 856 | #include <sstream>
 857 | 
 858 | int main( int argc, char **argv )
 859 | {
 860 |     std::cout << max<int>( 2.2, 2.5 ) << std::endl;
 861 |     std::cout << max<float>( 2.2, 2.5 ) << std::endl;
 862 | }
 863 | 
864 |
865 |
866 |

7.3   Template class

867 |
 868 | template <class T>
 869 | class Foo {
 870 |     T _value;
 871 | 
 872 | public:
 873 |     Foo( T value ) : _value(value) { };
 874 | }
 875 | 
 876 | int main( int argc, char **argv )
 877 | {
 878 |     Foo<int> foo_int;
 879 |     Foo<float> foo_float;
 880 | }
 881 | 
882 |
883 |
884 |

7.4   Template specialization

885 |
 886 | #include <iostream>
 887 | 
 888 | template <class T>
 889 | class Foo {
 890 |     T _value;
 891 | public:
 892 |     Foo( T value ) : _value(value)
 893 |     {
 894 |         std::cout << "Generic constructor called" << std::endl;
 895 |     };
 896 | }
 897 | 
 898 | template <>
 899 | class Foo<float> {
 900 |     float _value;
 901 | public:
 902 |     Foo( float value ) : _value(value)
 903 |     {
 904 |         std::cout << "Specialized constructor called" << std::endl;
 905 |     };
 906 | }
 907 | 
 908 | int main( int argc, char **argv )
 909 | {
 910 |     Foo<int> foo_int;
 911 |     Foo<float> foo_float;
 912 | }
 913 | 
914 |
915 |
916 |

7.5   Exercices

917 |
    918 |
  1. Write a generic swap function
  2. 919 |
  3. Write a generic point structure
  4. 920 |
  5. Write templated factorial, power and exponential functions 921 | (exp(x) = sum_n x^n/n!, exp(-x) = 1/exp(x))
  6. 922 |
  7. Write a smart pointer class
  8. 923 |
924 |
925 |
926 |
927 |

8   Standard Template Library

928 |
929 |

8.1   Containers

930 |

STL containers are template classes that implement various ways of storing 931 | elements and accessing them.

932 |

Sequence containers:

933 |
    934 |
  • vector
  • 935 |
  • deque
  • 936 |
  • list
  • 937 |
938 |

Container adaptors:

939 |
    940 |
  • stack
  • 941 |
  • queue
  • 942 |
  • priority_queue
  • 943 |
944 |

Associative containers:

945 |
    946 |
  • set
  • 947 |
  • multiset
  • 948 |
  • map
  • 949 |
  • multimap
  • 950 |
  • bitset
  • 951 |
952 |

See http://www.cplusplus.com/reference/stl/ for more information.

953 |
 954 | #include <vector>
 955 | #include <map>
 956 | #include <string>
 957 | 
 958 | int main( int argc, char **argv )
 959 | {
 960 |     std::vector<int> v;
 961 |     v.push_back(1);
 962 |     v.push_back(2);
 963 |     v.push_back(3);
 964 | 
 965 |     std::map<std::string,int> m;
 966 |     m["one"] = 1;
 967 |     m["two"] = 2;
 968 |     m["three"] = 3;
 969 | 
 970 |     return 0;
 971 | }
 972 | 
973 |
974 |
975 |

8.2   Iterators

976 |

Iterators are a convebient tool to iterate over a container:

977 |
 978 | #include <map>
 979 | #include <string>
 980 | #include <iostream>
 981 | 
 982 | int main( int argc, char **argv )
 983 | {
 984 |     std::map<std::string,int> m;
 985 |     m["one"] = 1;
 986 |     m["two"] = 2;
 987 |     m["three"] = 3;
 988 | 
 989 |     std::map<std::string,int>::iterator iter;
 990 |     for( iter=m.begin(); iter != m.end(); ++iter )
 991 |     {
 992 |         std::cout << "map[" << iter->first << "] = "
 993 |                   << iter->second << std::endl;
 994 |     }
 995 |     return 0;
 996 | }
 997 | 
998 |
999 |
1000 |

8.3   Algorithms

1001 |

Algorithms from the STL offer fast, robust, tested and maintained code for a lot 1002 | of standard operations on ranged elements. Don't reinvent the wheel !

1003 |

Have a look at http://r0d.developpez.com/articles/algos-stl-fr/ (French) and 1004 | http://www.cplusplus.com/reference/algorithm/ for an overview.

1005 |
1006 | #include <vector>
1007 | #include <algorithm>
1008 | 
1009 | bool compare( const int & first, const int  & second )
1010 | {
1011 |     return (first < second);
1012 | }
1013 | 
1014 | int main( int argc, char **argv )
1015 | {
1016 |     std::vector<int> v(10);
1017 |     std::sort(v.begin(), v.end(), &compare);
1018 | 
1019 |     return 0;
1020 | }
1021 | 
1022 |
1023 |
1024 |

8.4   Exercices

1025 |
1026 |
    1027 |
  1. Write a template stack class using the STL vector class
  2. 1028 |
  3. Write a generic vector class with iterators and benchmark it againt the STL 1029 | vector class
  4. 1030 |
1031 |
1032 |
1033 |
1034 | 1084 |
1085 | 1086 | 1087 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | .. sectnum:: 2 | 3 | =============================================================================== 4 | C++ crash course for C programmers 5 | =============================================================================== 6 | :Author: `Nicolas P. Rougier `_ 7 | :Sources: `crash-course.rst `_ 8 | 9 | .. contents:: 10 | :local: 11 | :depth: 2 12 | 13 | Foreword 14 | =============================================================================== 15 | This is an introduction to C++ for C programmers: 16 | 17 | * If you can't understand the code below, you'd better start with a C tutorial. 18 | 19 | .. code:: c++ 20 | 21 | #include 22 | 23 | void main (int argc, char **argv) 24 | { 25 | printf("Hello World!\n"); 26 | } 27 | 28 | * If you don't know what are the stack and the heap, you'd better have a look at 29 | some architecture & system introduction. 30 | * If you know java, that might help a bit. 31 | * If you think `python `_ is cool, you're right, but 32 | still, this is not the place. 33 | * If you never heard about `Bjarne Stroustrup 34 | `_, you might be at the right place. 35 | 36 | * Here is a list of C++ specific keywords:: 37 | 38 | asm dynamic_cast namespace reinterpret_cast try 39 | bool explicit new static_cast typeid 40 | catch false operator template typename 41 | class friend private this using 42 | const_cast inline public throw virtual 43 | delete mutable protected true wchar_t 44 | 45 | 46 | 47 | 48 | From C to C++ 49 | =============================================================================== 50 | 51 | Even if C++ is slanted toward object-oriented programming (OOP), you can 52 | nevertheless use any c++ compiler to compile c code and benefits from some c++ 53 | goodies. 54 | 55 | 56 | Input/Output 57 | ------------ 58 | 59 | Prefer the use of ```` for input/output operations (see stream 60 | section for explanation). 61 | 62 | .. code:: c++ 63 | 64 | #include 65 | 66 | int main (int argc, char **argv) 67 | { 68 | int i; 69 | std::cout << "Please enter an integer value: "; 70 | std::cin >> i; 71 | std::cout << "The value you entered is " << i << std::endl; 72 | return 0; 73 | } 74 | 75 | 76 | New/Delete 77 | ---------- 78 | 79 | The ``new`` and ``delete`` keywords are used to allocate and free memory. They 80 | are "object-aware" so you'd better use them instead of ``malloc`` and 81 | ``free``. In any case, never cross the streams (new/free or malloc/delete). 82 | 83 | .. code:: c++ 84 | 85 | int *a = new int; 86 | delete a; 87 | 88 | int *b = new int[5]; 89 | delete [] b; 90 | 91 | ``delete`` does two things: it calls the destructor and it deallocates the 92 | memory. 93 | 94 | References 95 | ---------- 96 | 97 | A reference allows to declare an alias to another variable. As long as the 98 | aliased variable lives, you can use indifferently the variable or the alias. 99 | 100 | .. code:: c++ 101 | 102 | int x; 103 | int& foo = x; 104 | 105 | foo = 42; 106 | std::cout << x << std::endl; 107 | 108 | References are extremely useful when used with function arguments since it 109 | saves the cost of copying parameters into the stack when calling the function. 110 | 111 | Default parameters 112 | ------------------ 113 | 114 | You can specify default values for function parameters. When the function is 115 | called with fewer parameters, default values are used. 116 | 117 | .. code:: c++ 118 | 119 | float foo( float a=0, float b=1, float c=2 ) 120 | {return a+b+c;} 121 | 122 | cout << foo(1) << endl 123 | << foo(1,2) << endl 124 | << foo(1,2,3) << endl; 125 | 126 | You should obtain values 4, 5 and 6. 127 | 128 | 129 | Namespaces 130 | ---------- 131 | 132 | Namespace allows to group classes, functions and variable under a common scope 133 | name that can be referenced elsewhere. 134 | 135 | .. code:: c++ 136 | 137 | namespace first { int var = 5; } 138 | namespace second { int var = 3; } 139 | cout << first::var << endl << second::var << endl; 140 | 141 | You should obtain values 3 and 5. There exists some standard namespace in the 142 | standard template library such as std. 143 | 144 | 145 | Overloading 146 | ----------- 147 | 148 | Function overloading refers to the possibility of creating multiple functions 149 | with the same name as long as they have different parameters (type and/or 150 | number). 151 | 152 | .. code:: c++ 153 | 154 | float add( float a, float b ) 155 | {return a+b;} 156 | 157 | int add( int a, int b ) 158 | {return a+b;} 159 | 160 | It is not legal to overload a function based on the return type (but you can do it 161 | `anyway 162 | `_) 163 | 164 | Const & inline 165 | -------------- 166 | 167 | Defines and macros are bad if not used properly as illustrated below 168 | 169 | .. code:: c++ 170 | 171 | #define SQUARE(x) x*x 172 | 173 | int result = SQUARE(3+3); 174 | 175 | For constants, prefer the const notation: 176 | 177 | .. code:: c++ 178 | 179 | const int two = 2; 180 | 181 | For macros, prefer the inline notation: 182 | 183 | .. code:: c++ 184 | 185 | int inline square(int x) 186 | { 187 | return x*x; 188 | } 189 | 190 | Mixing C and C++ 191 | ---------------- 192 | 193 | .. code:: c++ 194 | 195 | #ifdef __cplusplus 196 | extern "C" { 197 | #endif 198 | 199 | #include "some-c-code.h" 200 | 201 | #ifdef __cplusplus 202 | } 203 | #endif 204 | 205 | 206 | 207 | Exercises 208 | --------- 209 | 210 | 1. Write a basic makefile for compiling sources 211 | 212 | **solution**: `Makefile `_ 213 | 214 | 2. How would you declare: 215 | 216 | * A pointer to a char 217 | * A constant pointer to a char 218 | * A pointer to a constant char 219 | * A constant pointer to a constant char 220 | * A reference to a char 221 | * A reference to a constant char 222 | 223 | **solution**: `crash-course-2.1.cc `_ 224 | 225 | 3. Create a two-dimensional array of integers (size is n x n), fill it with 226 | corresponding indices (a[i][j] = i*n+j), test it and finally, delete it. 227 | 228 | **solution**: `crash-course-2.2.cc `_ 229 | 230 | 4. Write a function that swap two integers, then two pointers. 231 | 232 | **solution**: `crash-course-2.3.cc `_ 233 | 234 | 5. Is this legal ? 235 | 236 | .. code:: c++ 237 | 238 | int add( int a, int b ) { return a+b; } 239 | 240 | int add( int a, int b, int c=0 ) { return a+b+c; } 241 | 242 | **solution**: `crash-course-2.4.cc `_ 243 | 244 | 6. Write a ``const correct`` division function. 245 | 246 | **solution**: `crash-course-2.5.cc `_ 247 | 248 | 7. What's the difference between ``int const* p``, ``int* const p`` 249 | and ``int const* const p`` ? 250 | 251 | **solution**: `crash-course-2.6.cc `_ 252 | 253 | 254 | 255 | Classes 256 | =============================================================================== 257 | 258 | A class might be considered as an extended concept of a data structure: instead 259 | of holding only data, it can hold both data and functions. An object is an 260 | instantiation of a class. By default, all attributes and functions of a class 261 | are private (see below Access control). If you want a public default behavior, 262 | you can use keyword ``struct`` instead of keyword ``class`` in the declaration. 263 | 264 | .. code:: c++ 265 | 266 | class Foo { 267 | int attribute; 268 | int function( void ) { }; 269 | }; 270 | 271 | struct Bar { 272 | int attribute; 273 | int function( void ) { }; 274 | }; 275 | 276 | Foo foo; 277 | foo.attribute = 1; // WRONG 278 | 279 | Bar bar; 280 | bar.attribute = 1; // OK 281 | 282 | 283 | Constructors 284 | ------------ 285 | 286 | It is possible to specify zero, one or more constructors for the class. 287 | 288 | .. code:: c++ 289 | 290 | #include 291 | 292 | class Foo { 293 | public: 294 | Foo( void ) 295 | { std::cout << "Foo constructor 1 called" << std::endl; } 296 | Foo( int value ) 297 | { std::cout << "Foo constructor 2 called" << std::endl; } 298 | }; 299 | 300 | int main( int argc, char **argv ) 301 | { 302 | Foo foo_1, foo_2(2); 303 | return 0; 304 | } 305 | 306 | 307 | Destructor 308 | ---------- 309 | 310 | There can be only one destructor per class. It takes no argument and returns 311 | nothing. 312 | 313 | .. code:: c++ 314 | 315 | #include 316 | 317 | class Foo { 318 | public: 319 | ~Foo( void ) 320 | { std::cout << "Foo destructor called" << std::endl; } 321 | } 322 | int main( int argc, char **argv ) 323 | { 324 | Foo foo; 325 | return 0; 326 | } 327 | 328 | Note that you generally never need to explicitly call a destructor. 329 | 330 | 331 | Access control 332 | -------------- 333 | 334 | You can have fine control over who is granted access to a class function or 335 | attribute by specifying an explicit access policy: 336 | 337 | * **public**: Anyone is granted access 338 | * **protected**: Only derived classes are granted access 339 | * **private**: No one but friends are granted access 340 | 341 | 342 | Initialization list 343 | ------------------- 344 | 345 | Object's member should be initialized using initialization lists 346 | 347 | .. code:: c++ 348 | 349 | class Foo 350 | { 351 | int _value; 352 | public: 353 | Foo(int value=0) : _value(value) { }; 354 | }; 355 | 356 | It's cheaper, better and faster. 357 | 358 | 359 | Operator overloading 360 | -------------------- 361 | 362 | .. code:: c++ 363 | 364 | class Foo { 365 | private: 366 | int _value; 367 | 368 | public: 369 | Foo( int value ) : _value(value) { }; 370 | 371 | Foo operator+ ( const Foo & other ) 372 | { 373 | return Foo( _value+ other._value ); 374 | } 375 | 376 | Foo operator* ( const Foo & other ); 377 | { 378 | return Foo( _value * other._value ); 379 | } 380 | } 381 | 382 | 383 | Friends 384 | ------- 385 | 386 | Friends are either functions or other classes that are granted privileged 387 | access to a class. 388 | 389 | .. code:: c++ 390 | 391 | #include 392 | 393 | class Foo { 394 | public: 395 | friend std::ostream& operator<< ( std::ostream& output, 396 | Foo const & that ) 397 | { 398 | return output << that._value; 399 | } 400 | private: 401 | double _value; 402 | }; 403 | 404 | int main( int argc, char **argv ) 405 | { 406 | Foo foo; 407 | std::cout << "Foo object: " << foo << std::endl; 408 | return 0 409 | } 410 | 411 | Exercises 412 | --------- 413 | 414 | 1. Why the following code doesn't compile ? 415 | 416 | .. code:: c++ 417 | 418 | class Foo { Foo () { }; }; 419 | 420 | int main( int argc, char **argv ) 421 | { 422 | Foo foo; 423 | } 424 | 425 | **solution**: `crash-course-3.1.cc `_ 426 | 427 | 2. Write a ``Foo`` class with default and copy constructors and add also an 428 | assignment operator. Write some code to highlight the use of each of them. 429 | 430 | **solution**: `crash-course-3.2.cc `_ 431 | 432 | 3. Write a ``Point`` class that can be constructed using cartesian or polar 433 | coordinates. 434 | 435 | **solution**: `crash-course-3.3.cc `_ 436 | 437 | 4. Write a ``Foo`` class and provide it with an input method. 438 | 439 | **solution**: `crash-course-3.4.cc `_ 440 | 441 | 5. Is is possible to write something like ``foo.method1().method2()`` ? 442 | 443 | **solution**: `crash-course-3.5.cc `_ 444 | 445 | 446 | Inheritance 447 | =============================================================================== 448 | 449 | Basics 450 | ------ 451 | 452 | Inheritance is done at the class definition level by specifying the base class 453 | and the type of inheritance. 454 | 455 | .. code:: c++ 456 | 457 | class Foo { /* ... */ }; 458 | class Bar_public : public Foo { /* ... */ }; 459 | class Bar_private : private Foo { /* ... */ }; 460 | class Bar_protected : protected Foo { /* ... */ }; 461 | 462 | ``Bar_public``, ``Bar_private`` and ``Bar_protected`` are derived from ``Foo``. 463 | ``Foo`` is the base class of ``Bar_public``, ``Bar_private`` and ``Bar_protected``. 464 | 465 | * In ``Bar_public``, public parts of ``Foo`` are public, 466 | protected parts of ``Foo`` are protected 467 | * In ``Bar_private``, public and protected parts of ``Foo`` are private 468 | * In ``Bar_protected``, public and protected parts of ``Foo`` are protected 469 | 470 | 471 | Virtual methods 472 | --------------- 473 | 474 | A ``virtual`` function allows derived classes to replace the implementation 475 | provided by the base class (yes, it is not automatic...). Non virtual methods 476 | are resolved statically (at compile time) while virtual methods are resolved 477 | dynamically (at run time). 478 | 479 | .. code:: c++ 480 | 481 | class Foo { 482 | public: 483 | Foo( void ); 484 | void method1( void ); 485 | virtual void method2( void ); 486 | }; 487 | 488 | class Bar : public Foo { 489 | public: 490 | Bar( void ); 491 | void method1( void ); 492 | void method2( void ); 493 | }; 494 | 495 | Foo *bar = new Bar(); 496 | bar->method1(); 497 | bar->method2(); 498 | 499 | Make sure your destructor is virtual when you have derived class. 500 | 501 | 502 | Abstract classes 503 | ---------------- 504 | 505 | You can define pure virtual method that prohibits the base object to be 506 | instantiated. Derived classes need then to implement the virtual method. 507 | 508 | .. code:: c++ 509 | 510 | class Foo { 511 | public: 512 | Foo( void ); 513 | virtual void method( void ) = 0; 514 | }; 515 | 516 | class Bar: public Foo { 517 | public: 518 | Foo( void ); 519 | void method( void ) { }; 520 | }; 521 | 522 | 523 | 524 | Multiple inheritance 525 | -------------------- 526 | 527 | A class may inherit from multiple base classes but you have to be careful: 528 | 529 | .. code:: c++ 530 | 531 | class Foo { protected: int data; }; 532 | class Bar1 : public Foo { /* ... */ }; 533 | class Bar2 : public Foo { /* ... */ }; 534 | class Bar3 : public Bar1, public Bar2 { 535 | void method( void ) 536 | { 537 | data = 1; // !!! BAD 538 | } 539 | }; 540 | 541 | In class Bar3, the ``data`` reference is ambiguous since it could refer to 542 | Bar1::data or Bar2::data. This problem is referred as the **diamond 543 | problem**. You can eliminate the problem by explicitly specifying the data 544 | origin (e.g. Bar1::data) or by using virtual inheritance in Bar1 and Bar2. 545 | 546 | 547 | Exercises 548 | --------- 549 | 550 | 1. Write a ``Bar`` class that inherits from a ``Foo`` class and makes 551 | constructor and destructor methods to print something when called. 552 | 553 | **solution**: `crash-course-4.1.cc `_ 554 | 555 | 2. Write a ``foo`` function and make it called from a class that has 556 | a ``foo`` method. 557 | 558 | **solution**: `crash-course-4.2.cc `_ 559 | 560 | 3. Write a ``Real`` base class and a derived ``Integer`` class with all common 561 | operators (+,-,*,/) 562 | 563 | **solution**: `crash-course-4.3.cc `_ 564 | 565 | 4. Write a ``Singleton`` class such that only one object of this class can be 566 | created. 567 | 568 | **solution**: `crash-course-4.4.cc `_ 569 | 570 | 5. Write a functor class 571 | 572 | **solution**: `crash-course-4.5.cc `_ 573 | 574 | 575 | 576 | 577 | 578 | Exceptions 579 | =============================================================================== 580 | 581 | The Zen of Python 582 | ----------------- 583 | (by Tim Peters) 584 | 585 | | Beautiful is better than ugly. 586 | | Explicit is better than implicit. 587 | | Simple is better than complex. 588 | | Complex is better than complicated. 589 | | Flat is better than nested. 590 | | Sparse is better than dense. 591 | | Readability counts. 592 | | Special cases aren't special enough to break the rules. 593 | | Although practicality beats purity. 594 | | **Errors should never pass silently.** 595 | | **Unless explicitly silenced.** 596 | | In the face of ambiguity, refuse the temptation to guess. 597 | | There should be one-- and preferably only one --obvious way to do it. 598 | | Although that way may not be obvious at first unless you're Dutch. 599 | | Now is better than never. 600 | | Although never is often better than *right* now. 601 | | If the implementation is hard to explain, it's a bad idea. 602 | | If the implementation is easy to explain, it may be a good idea. 603 | | Namespaces are one honking great idea -- let's do more of those! 604 | 605 | 606 | Catch me if you can 607 | ------------------- 608 | 609 | You can catch any exception using the following structure: 610 | 611 | .. code:: c++ 612 | 613 | try 614 | { 615 | float *array = new float[-1]; 616 | } 617 | catch( std::bad_alloc e ) 618 | { 619 | std::cerr << e.what() << std::endl; 620 | } 621 | 622 | If the raised exception is different from the ones you're catching, program 623 | will stop. 624 | 625 | 626 | Creating your own exception 627 | --------------------------- 628 | 629 | Creating a new exception is quite easy: 630 | 631 | .. code:: c++ 632 | 633 | #include 634 | 635 | class Exception : public std::runtime_error 636 | { 637 | public: 638 | Exception() : std::runtime_error("Exception") { }; 639 | }; 640 | 641 | 642 | Standard exceptions 643 | ------------------- 644 | 645 | There exist some standard exceptions that can be raised in some circumstances: 646 | 647 | ``#include `` 648 | 649 | * bad_alloc 650 | * bad_cast 651 | * bad_exception 652 | * bad_typeid 653 | * logic_error 654 | 655 | * domain_error 656 | * invalid_argument 657 | * length_error 658 | * out_of_range 659 | 660 | * runtime_error 661 | 662 | * range_error 663 | * overflow_error 664 | * underflow_error 665 | 666 | 667 | 668 | Exercises 669 | --------- 670 | 671 | 1. How to handle a constructor that fails ? 672 | 673 | **solution**: `crash-course-5.1.cc `_ 674 | 675 | 2. Write a program that raise 3 of the standard exceptions. 676 | 677 | **solution**: `crash-course-5.2.cc `_ 678 | 679 | 3. Write a correct division function. 680 | 681 | **solution**: `crash-course-5.3.cc `_ 682 | 683 | 4. Write a ``Integer`` (positive) class with proper exception handling 684 | (``Overflow``, ``Underflow``, ``DivideByZero``, etc.) 685 | 686 | **solution**: `crash-course-5.4.cc `_ 687 | 688 | 689 | 690 | Streams 691 | =============================================================================== 692 | 693 | C++ provides input/output capability through the iostream classes that provide 694 | the stream concept (iXXXstream for input and oXXXstream for output). 695 | 696 | iostream and ios 697 | ---------------- 698 | 699 | Screen outputs and keyboard inputs may be handled using the iostream header 700 | file: 701 | 702 | .. code:: c++ 703 | 704 | #include 705 | 706 | int main( int argc, char **argv ) 707 | { 708 | 709 | unsigned char age = 65; 710 | std::cout << static_cast(age) << std::endl; 711 | std::cout << static_cast(&age) << std::endl; 712 | 713 | double f = 3.14159; 714 | cout.unsetf(ios::floatfield); 715 | cout.precision(5); 716 | cout << f << endl; 717 | cout.precision(10); 718 | cout << f << endl; 719 | cout.setf(ios::fixed,ios::floatfield); 720 | cout << f << endl; 721 | 722 | std::cout << "Enter a number, or -1 to quit: "; 723 | int i = 0; 724 | while( std::cin >> i ) 725 | { 726 | if (i == -1) break; 727 | std::cout << "You entered " << i << '\n'; 728 | } 729 | return 0; 730 | } 731 | 732 | 733 | Class input/output 734 | ------------------ 735 | 736 | You can implement a class input and output using friends functions: 737 | 738 | .. code:: c++ 739 | 740 | #include 741 | 742 | class Foo { 743 | public: 744 | friend std::ostream& operator<< ( std::ostream & output, Foo const & that ) 745 | { return output << that._value; } 746 | friend std::istream& operator>> ( std::istream & input, Foo& foo ) 747 | { return input >> fred._value; } 748 | 749 | private: 750 | double _value; 751 | }; 752 | 753 | Working with files 754 | ------------------ 755 | 756 | .. code:: c++ 757 | 758 | #include 759 | 760 | int main( int argc, char **argv ) 761 | { 762 | std::ifstream input( filename ); 763 | // std::ifstream input( filename, std::ios::in | std::ios::binary); 764 | 765 | std::ofstream output( filename ); 766 | // std::ofstream output( filename, std::ios::out | std::ios::binary); 767 | 768 | return 0; 769 | } 770 | 771 | 772 | 773 | Working with strings 774 | -------------------- 775 | 776 | .. code:: c++ 777 | 778 | #include 779 | 780 | int main( int argc, char **argv ) 781 | { 782 | const char *svalue = "42.0"; 783 | int ivalue; 784 | std::istringstream istream; 785 | std::ostringstream ostream; 786 | 787 | istream.str(svalue); 788 | istream >> ivalue; 789 | std::cout << svalue << " = " << ivalue << std::endl; 790 | 791 | ostream.clear(); 792 | ostream << ivalue; 793 | std::cout << ivalue << " = " << ostream.str() << std::endl; 794 | 795 | return 0; 796 | } 797 | 798 | 799 | Exercises 800 | --------- 801 | 802 | 1. Write an ``itoa`` and an ``atoi`` function 803 | 2. Write a foo class with some attributes and write functions for writing to 804 | file and reading from file. 805 | 806 | 807 | 808 | Templates 809 | =============================================================================== 810 | 811 | Templates are special operators that specify that a class or a function is 812 | written for one or several generic types that are not yet known. The format for 813 | declaring function templates is: 814 | 815 | * template function_declaration; 816 | * template class_declaration; 817 | 818 | You can have several templates and to actually use a class or function 819 | template, you have to specify all unknown types: 820 | 821 | .. code:: c++ 822 | 823 | template 824 | T1 foo1( void ) { /* ... */ }; 825 | 826 | template 827 | T1 foo2( void ) { /* ... */ }; 828 | 829 | template 830 | class Foo3 { /* ... */ }; 831 | 832 | 833 | int a = foo1(); 834 | float b = foo2(); 835 | Foo c; 836 | 837 | Template parameters 838 | ------------------- 839 | 840 | There are three possible template types: 841 | 842 | * **Type** 843 | 844 | .. code:: c++ 845 | 846 | template T foo( void ) { /* ... */ }; 847 | 848 | 849 | * **Non-type** 850 | 851 | .. code:: c++ 852 | 853 | template foo( void ) { /* ... */ }; 854 | 855 | 856 | * **Template** 857 | 858 | .. code:: c++ 859 | 860 | template< template > foo( void ) { /* ... */ }; 861 | 862 | 863 | Template function 864 | ----------------- 865 | 866 | .. code:: c++ 867 | 868 | template 869 | T max( T a, T b) 870 | { 871 | return( a > b ? a : b ); 872 | } 873 | 874 | #include 875 | 876 | int main( int argc, char **argv ) 877 | { 878 | std::cout << max( 2.2, 2.5 ) << std::endl; 879 | std::cout << max( 2.2, 2.5 ) << std::endl; 880 | } 881 | 882 | 883 | 884 | Template class 885 | -------------- 886 | 887 | .. code:: c++ 888 | 889 | template 890 | class Foo { 891 | T _value; 892 | 893 | public: 894 | Foo( T value ) : _value(value) { }; 895 | } 896 | 897 | int main( int argc, char **argv ) 898 | { 899 | Foo foo_int; 900 | Foo foo_float; 901 | } 902 | 903 | 904 | Template specialization 905 | ----------------------- 906 | 907 | .. code:: c++ 908 | 909 | #include 910 | 911 | template 912 | class Foo { 913 | T _value; 914 | public: 915 | Foo( T value ) : _value(value) 916 | { 917 | std::cout << "Generic constructor called" << std::endl; 918 | }; 919 | } 920 | 921 | template <> 922 | class Foo { 923 | float _value; 924 | public: 925 | Foo( float value ) : _value(value) 926 | { 927 | std::cout << "Specialized constructor called" << std::endl; 928 | }; 929 | } 930 | 931 | int main( int argc, char **argv ) 932 | { 933 | Foo foo_int; 934 | Foo foo_float; 935 | } 936 | 937 | 938 | Exercises 939 | --------- 940 | 941 | 1. Write a generic swap function 942 | 2. Write a generic point structure 943 | 3. Write templated factorial, power and exponential functions 944 | (exp(x) = sum_n x^n/n!, exp(-x) = 1/exp(x)) 945 | 4. Write a smart pointer class 946 | 947 | 948 | 949 | 950 | 951 | Standard Template Library 952 | =============================================================================== 953 | 954 | Containers 955 | ---------- 956 | 957 | STL containers are template classes that implement various ways of storing 958 | elements and accessing them. 959 | 960 | **Sequence containers**: 961 | 962 | * vector 963 | * deque 964 | * list 965 | 966 | **Container adaptors**: 967 | 968 | * stack 969 | * queue 970 | * priority_queue 971 | 972 | **Associative containers**: 973 | 974 | * set 975 | * multiset 976 | * map 977 | * multimap 978 | * bitset 979 | 980 | See http://www.cplusplus.com/reference/stl/ for more information. 981 | 982 | 983 | .. code:: c++ 984 | 985 | #include 986 | #include 987 | #include 988 | 989 | int main( int argc, char **argv ) 990 | { 991 | std::vector v; 992 | v.push_back(1); 993 | v.push_back(2); 994 | v.push_back(3); 995 | 996 | std::map m; 997 | m["one"] = 1; 998 | m["two"] = 2; 999 | m["three"] = 3; 1000 | 1001 | return 0; 1002 | } 1003 | 1004 | 1005 | Iterators 1006 | --------- 1007 | 1008 | Iterators are a convenient tool to iterate over a container: 1009 | 1010 | .. code:: c++ 1011 | 1012 | #include 1013 | #include 1014 | #include 1015 | 1016 | int main( int argc, char **argv ) 1017 | { 1018 | std::map m; 1019 | m["one"] = 1; 1020 | m["two"] = 2; 1021 | m["three"] = 3; 1022 | 1023 | std::map::iterator iter; 1024 | for( iter=m.begin(); iter != m.end(); ++iter ) 1025 | { 1026 | std::cout << "map[" << iter->first << "] = " 1027 | << iter->second << std::endl; 1028 | } 1029 | return 0; 1030 | } 1031 | 1032 | 1033 | 1034 | Algorithms 1035 | ---------- 1036 | 1037 | Algorithms from the STL offer fast, robust, tested and maintained code for a lot 1038 | of standard operations on ranged elements. Don't reinvent the wheel ! 1039 | 1040 | Have a look at http://r0d.developpez.com/articles/algos-stl-fr/ (French) and 1041 | http://www.cplusplus.com/reference/algorithm/ for an overview. 1042 | 1043 | .. code:: c++ 1044 | 1045 | #include 1046 | #include 1047 | 1048 | bool compare( const int & first, const int & second ) 1049 | { 1050 | return (first < second); 1051 | } 1052 | 1053 | int main( int argc, char **argv ) 1054 | { 1055 | std::vector v(10); 1056 | std::sort(v.begin(), v.end(), &compare); 1057 | 1058 | return 0; 1059 | } 1060 | 1061 | 1062 | Exercises 1063 | --------- 1064 | 1. Write a template stack class using the STL vector class 1065 | 2. Write a generic vector class with iterators and benchmark it against the STL 1066 | vector class 1067 | 1068 | 1069 | 1070 | External links 1071 | =============================================================================== 1072 | 1073 | * | C++ FAQ — Frequently Asked Questions 1074 | | http://www.parashift.com/c++-faq-lite/ 1075 | 1076 | * | Boost free peer-reviewed portable C++ source libraries 1077 | | http://www.boost.org/ 1078 | 1079 | * | Bjarne Stroustrup homepage 1080 | | http://www2.research.att.com/~bs/ 1081 | 1082 | * | Complete reference on C++ Standard Library 1083 | | http://en.cppreference.com/w/cpp 1084 | 1085 | * | C++11 main features 1086 | | http://en.wikipedia.org/wiki/C%2B%2B11 1087 | 1088 | * | The definitive C++ book guide 1089 | | http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list 1090 | 1091 | * | comp.lang.c++ 1092 | | http://groups.google.com/group/comp.lang.c++/topics 1093 | 1094 | * | GNU make 1095 | | http://www.gnu.org/s/make/manual/make.html 1096 | 1097 | * | Les meilleurs cours et tutoriaux (in **French** as you may have already guessed...) 1098 | | http://cpp.developpez.com/cours/ 1099 | -------------------------------------------------------------------------------- /exam.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | C++ exam 8 | 9 | 10 | 11 |
12 |

C++ exam

13 | 14 |

Name:

15 |

Surname:

16 |
17 |

1   Extern

18 |

The code below declares and defines variable x. True or False ?

19 |
 20 | extern int x;
 21 | 
22 |
23 |
24 |

2   Namespace

25 |

In namespace foo, the function bar can access the variable x also declared in 26 | namespace foo ? True or False ?

27 |
 28 | #include <iostream>
 29 | 
 30 | namespace foo
 31 | {
 32 |     void bar()
 33 |     {
 34 |         x++;
 35 |     }
 36 |     int x;
 37 | }
 38 | 
 39 | int main(int argc, char** argv)
 40 | {
 41 |     return 0;
 42 | }
 43 | 
44 |
45 |
46 |

3   References

47 |

What is the output of the following program ?

48 |
 49 | #include <iostream>
 50 | using namespace std;
 51 | 
 52 | void swap1( int  a, int  b ) { int c=a; a=b; b=c; }
 53 | void swap2( int *a, int *b ) { int c=*a; *a=*b; *b=c; }
 54 | void swap3( int &a, int &b ) { int &c=a; a=b; b=c; }
 55 | 
 56 | int main( int argc, char **argv )
 57 | {
 58 |     int a, b;
 59 | 
 60 |     a = 1; b = 2; swap1(a,b);
 61 |     cout << "a: " << a << ", " <<"b: " << b << endl;
 62 | 
 63 |     a = 1; b = 2; swap2(&a,&b);
 64 |     cout << "a: " << a << ", " <<"b: " << b << endl;
 65 | 
 66 |     a = 1; b = 2; swap3(a,b);
 67 |     cout << "a: " << a << ", " <<"b: " << b << endl;
 68 | }
 69 | 
70 |
71 |
72 |

4   Inheritance

73 |

What is the output of the program ?

74 |
 75 | #include <iostream>
 76 | 
 77 | struct A { unsigned int color; };
 78 | struct B : public A { };
 79 | struct C : public A { };
 80 | struct D : public B, public C { };
 81 | 
 82 | int main(int argc, char** argv)
 83 | {
 84 |    D d;
 85 |    d.color = 3;
 86 |    std::cout << d.color << std::endl;
 87 |    return 0;
 88 | }
 89 | 
90 |
91 |
92 |

5   Inheritance

93 |

How many times is "Hello World" printed by this program ?

94 |
 95 | #include <iostream>
 96 | 
 97 | struct A { A() {  std::cout << "Hello World" << std::endl; } };
 98 | struct A1 : public A { };
 99 | struct A2 : public A { };
100 | struct A3 : public A { };
101 | struct A4 : public A { };
102 | struct B : public A1, public A2, public A3, public A4 { };
103 | 
104 | int main(int argc, char** argv)
105 | {
106 |     B b;
107 |     return 0;
108 | }
109 | 
110 |
111 |
112 |

6   Initialization

113 |

What is the value of x, y & z ?

114 |
115 | #include <iostream>
116 | 
117 | struct A
118 | {
119 |   A(int n) : x(n++), y(n++), z(n++) {}
120 |   int x;
121 |   int y;
122 |   int z;
123 | };
124 | 
125 | int main(int argc, char** argv)
126 | {
127 |   Foo f(3);
128 | 
129 |   std::cout << "x: " << f.x << std::endl;
130 |   std::cout << "y: " << f.y << std::endl;
131 |   std::cout << "z: " << f.z << std::endl;
132 | 
133 |   return 0;
134 | }
135 | 
136 |
137 |
138 |

7   Logic

139 |

What value gets printed by the program?

140 |
141 | #include <iostream>
142 | 
143 | int main(int argc, char** argv)
144 | {
145 |   int x = 0;
146 |   int y = 0;
147 | 
148 |   if (x++ && y++)
149 |   {
150 |     y += 2;
151 |   }
152 | 
153 |   std::cout << x + y << std::endl;
154 | 
155 |   return 0;
156 | }
157 | 
158 |
159 |
160 |

8   Constructors

161 |

Which lines below should not compile ?

162 |
163 | struct A
164 | {
165 |    A(int x) : n(x) {}
166 |    int n;
167 | };
168 | 
169 | int main(int argc, char** argv)
170 | {
171 |   A a1;
172 |   A a2(2);
173 |   A a3(a2);
174 |   return 0;
175 | }
176 | 
177 |
178 |
179 |

9   Memory

180 |

Which of the following implementations of the reset function is best for 181 | initializing the array to all zero.

182 |
183 | class foo{
184 | public:
185 |     foo(){
186 |         reset();
187 |     }
188 | private:
189 |     void reset(){
190 | 
191 |     // A // memset(x, 0, 50);
192 |     // B // memset(x, 0, sizeof(x));
193 |     // C // memset(x, 0, 50 * 4);
194 |     // D // memset(x, 0, 50 * sizeof(x));
195 |     }
196 | 
197 |     long x[50];
198 | };
199 | 
200 |
201 |
202 |

10   References

203 |

What is the output of the program ?

204 |
205 | #include <iostream>
206 | 
207 | int main(int argc, char** argv)
208 | {
209 |   // assume address of x is 0x822222222
210 |   int x = 3;
211 | 
212 |   int*& rpx = &x;
213 | 
214 |   std::cout << rpx << std::endl;
215 | 
216 |   return 0;
217 | }
218 | 
219 |
220 |
221 |

11   End

222 |
223 |
224 | 225 | 226 | -------------------------------------------------------------------------------- /exam.rst: -------------------------------------------------------------------------------- 1 | .. sectnum:: 2 | 3 | =============================================================================== 4 | C++ exam 5 | =============================================================================== 6 | 7 | Name: 8 | 9 | 10 | .. :Author: `Nicolas P. Rougier `_ 11 | .. :Sources: `exam.rst `_ 12 | .. Most questions comes from http://www.mycppquiz.com/ 13 | 14 | 15 | Extern 16 | =============================================================================== 17 | 18 | The code below declares and defines variable x. **True** or **False** ? 19 | 20 | .. code:: c++ 21 | 22 | extern int x; 23 | 24 | 25 | Namespace 26 | =============================================================================== 27 | In namespace foo, the function bar can access the variable x also declared in 28 | namespace foo ? **True** or **False** ? 29 | 30 | .. code:: c++ 31 | 32 | #include 33 | 34 | namespace foo 35 | { 36 | void bar() 37 | { 38 | x++; 39 | } 40 | int x; 41 | } 42 | 43 | int main(int argc, char** argv) 44 | { 45 | return 0; 46 | } 47 | 48 | 49 | References 50 | =============================================================================== 51 | What is the output of the following program ? 52 | 53 | .. code:: c++ 54 | 55 | #include 56 | using namespace std; 57 | 58 | void swap1( int a, int b ) { int c=a; a=b; b=c; } 59 | void swap2( int *a, int *b ) { int c=*a; *a=*b; *b=c; } 60 | void swap3( int &a, int &b ) { int &c=a; a=b; b=c; } 61 | 62 | int main( int argc, char **argv ) 63 | { 64 | int a, b; 65 | 66 | a = 1; b = 2; swap1(a,b); 67 | cout << "a: " << a << ", " <<"b: " << b << endl; 68 | 69 | a = 1; b = 2; swap2(&a,&b); 70 | cout << "a: " << a << ", " <<"b: " << b << endl; 71 | 72 | a = 1; b = 2; swap3(a,b); 73 | cout << "a: " << a << ", " <<"b: " << b << endl; 74 | } 75 | 76 | 77 | Inheritance 78 | =============================================================================== 79 | What is the output of the program ? 80 | 81 | .. code:: c++ 82 | 83 | #include 84 | 85 | struct A { unsigned int color; }; 86 | struct B : public A { }; 87 | struct C : public A { }; 88 | struct D : public B, public C { }; 89 | 90 | int main(int argc, char** argv) 91 | { 92 | D d; 93 | d.color = 3; 94 | std::cout << d.color << std::endl; 95 | return 0; 96 | } 97 | 98 | Inheritance 99 | =============================================================================== 100 | How many times is "Hello World" printed by this program ? 101 | 102 | .. code:: c++ 103 | 104 | #include 105 | 106 | struct A { A() { std::cout << "Hello World" << std::endl; } }; 107 | struct A1 : public A { }; 108 | struct A2 : public A { }; 109 | struct A3 : public A { }; 110 | struct A4 : public A { }; 111 | struct B : public A1, public A2, public A3, public A4 { }; 112 | 113 | int main(int argc, char** argv) 114 | { 115 | B b; 116 | return 0; 117 | } 118 | 119 | 120 | Initialization 121 | =============================================================================== 122 | What is the value of x, y & z ? 123 | 124 | .. code:: c++ 125 | 126 | #include 127 | 128 | struct A 129 | { 130 | A(int n) : x(n++), y(n++), z(n++) {} 131 | int x; 132 | int y; 133 | int z; 134 | }; 135 | 136 | int main(int argc, char** argv) 137 | { 138 | Foo f(3); 139 | 140 | std::cout << "x: " << f.x << std::endl; 141 | std::cout << "y: " << f.y << std::endl; 142 | std::cout << "z: " << f.z << std::endl; 143 | 144 | return 0; 145 | } 146 | 147 | 148 | Logic 149 | =============================================================================== 150 | What value gets printed by the program? 151 | 152 | .. code:: c++ 153 | 154 | #include 155 | 156 | int main(int argc, char** argv) 157 | { 158 | int x = 0; 159 | int y = 0; 160 | 161 | if (x++ && y++) 162 | { 163 | y += 2; 164 | } 165 | 166 | std::cout << x + y << std::endl; 167 | 168 | return 0; 169 | } 170 | 171 | Constructors 172 | =============================================================================== 173 | Which lines below should not compile ? 174 | 175 | .. code:: c++ 176 | 177 | struct A 178 | { 179 | A(int x) : n(x) {} 180 | int n; 181 | }; 182 | 183 | int main(int argc, char** argv) 184 | { 185 | A a1; 186 | A a2(2); 187 | A a3(a2); 188 | return 0; 189 | } 190 | 191 | 192 | 193 | Memory 194 | =============================================================================== 195 | Which of the following implementations of the reset function is best for 196 | initializing the array to all zero. 197 | 198 | .. code:: c++ 199 | 200 | class foo{ 201 | public: 202 | foo(){ 203 | reset(); 204 | } 205 | private: 206 | void reset(){ 207 | 208 | // A // memset(x, 0, 50); 209 | // B // memset(x, 0, sizeof(x)); 210 | // C // memset(x, 0, 50 * 4); 211 | // D // memset(x, 0, 50 * sizeof(x)); 212 | } 213 | 214 | long x[50]; 215 | }; 216 | 217 | 218 | References 219 | =============================================================================== 220 | What is the output of the program ? 221 | 222 | .. code:: c++ 223 | 224 | #include 225 | 226 | int main(int argc, char** argv) 227 | { 228 | // assume address of x is 0x822222222 229 | int x = 3; 230 | 231 | int*& rpx = &x; 232 | 233 | std::cout << rpx << std::endl; 234 | 235 | return 0; 236 | } 237 | 238 | 239 | End 240 | =============================================================================== 241 | -------------------------------------------------------------------------------- /exam/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2012 Nicolas P. Rougier 2 | # 3 | # This program is free software: you can redistribute it and/or modify it under 4 | # the terms of the GNU General Public License as published by the Free Software 5 | # Foundation, either version 3 of the License, or (at your option) any later 6 | # version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but WITHOUT 9 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 11 | 12 | # You should have received a copy of the GNU General Public License along with 13 | # this program. If not, see . 14 | PLATFORM = $(shell uname) 15 | CXX = g++ 16 | CXXFLAGS = -Wall -ansi -pedantic 17 | 18 | SOURCES:= $(wildcard *.cc) 19 | TARGETS := $(SOURCES:.cc=) 20 | 21 | all: $(TARGETS) 22 | 23 | 24 | define template 25 | $(1): $(1).cc 26 | @echo "Building $$@... " 27 | @$(CXX) $(1).cc $(CXXFLAGS) -o $$@ 28 | endef 29 | $(foreach target,$(TARGETS),$(eval $(call template,$(target)))) 30 | 31 | clean: 32 | @-rm -f $(TARGETS) 33 | 34 | distclean: clean 35 | @-rm -f *~ 36 | -------------------------------------------------------------------------------- /exam/exam-1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rougier/CPP-Crash-Course/9c975863975028b61f1b510bfc3ed9e306ec8701/exam/exam-1 -------------------------------------------------------------------------------- /exam/exam-1.cc: -------------------------------------------------------------------------------- 1 | 2 | extern int x; 3 | 4 | int main(int argc, char** argv) 5 | { 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /exam/exam-10: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rougier/CPP-Crash-Course/9c975863975028b61f1b510bfc3ed9e306ec8701/exam/exam-10 -------------------------------------------------------------------------------- /exam/exam-10.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char** argv) 4 | { 5 | // assume address of x is 0x822222222 6 | int x = 3; 7 | 8 | // int*& rpx = &x; 9 | // std::cout << rpx << std::endl; 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /exam/exam-2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rougier/CPP-Crash-Course/9c975863975028b61f1b510bfc3ed9e306ec8701/exam/exam-2 -------------------------------------------------------------------------------- /exam/exam-2.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace foo 4 | { 5 | void bar() 6 | { 7 | // x++; 8 | } 9 | int x; 10 | } 11 | 12 | int main(int argc, char** argv) 13 | { 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /exam/exam-3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rougier/CPP-Crash-Course/9c975863975028b61f1b510bfc3ed9e306ec8701/exam/exam-3 -------------------------------------------------------------------------------- /exam/exam-3.cc: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void swap1( int a, int b ) { int c=a; a=b; b=c; } 5 | void swap2( int *a, int *b ) { int c=*a; *a=*b; *b=c; } 6 | void swap3( int &a, int &b ) { int &c=a; a=b; b=c; } 7 | 8 | int main( int argc, char **argv ) 9 | { 10 | int a, b; 11 | 12 | a = 1; b = 2; swap1(a,b); 13 | cout << "a: " << a << ", " <<"b: " << b << endl; 14 | 15 | a = 1; b = 2; swap2(&a,&b); 16 | cout << "a: " << a << ", " <<"b: " << b << endl; 17 | 18 | a = 1; b = 2; swap3(a,b); 19 | cout << "a: " << a << ", " <<"b: " << b << endl; 20 | } 21 | -------------------------------------------------------------------------------- /exam/exam-4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rougier/CPP-Crash-Course/9c975863975028b61f1b510bfc3ed9e306ec8701/exam/exam-4 -------------------------------------------------------------------------------- /exam/exam-4.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct A { unsigned int color; }; 4 | struct B : public A { }; 5 | struct C : public A { }; 6 | struct D : public B, public C { }; 7 | 8 | int main(int argc, char** argv) 9 | { 10 | // D d; 11 | // d.color = 3; 12 | // std::cout << d.color << std::endl; 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /exam/exam-5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rougier/CPP-Crash-Course/9c975863975028b61f1b510bfc3ed9e306ec8701/exam/exam-5 -------------------------------------------------------------------------------- /exam/exam-5.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct A { A() { std::cout << "Hello World" << std::endl; } }; 4 | struct A1 : public A { }; 5 | struct A2 : public A { }; 6 | struct A3 : public A { }; 7 | struct A4 : public A { }; 8 | struct B : public A1, public A2, public A3, public A4 { }; 9 | 10 | int main(int argc, char** argv) 11 | { 12 | B b; 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /exam/exam-6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rougier/CPP-Crash-Course/9c975863975028b61f1b510bfc3ed9e306ec8701/exam/exam-6 -------------------------------------------------------------------------------- /exam/exam-6.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct Foo 4 | { 5 | Foo(int n) : x(n++), y(n++), z(n++) {} 6 | int x; 7 | int y; 8 | int z; 9 | }; 10 | 11 | int main(int argc, char** argv) 12 | { 13 | Foo f(3); 14 | 15 | std::cout << "x: " << f.x << std::endl; 16 | std::cout << "y: " << f.y << std::endl; 17 | std::cout << "z: " << f.z << std::endl; 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /exam/exam-7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rougier/CPP-Crash-Course/9c975863975028b61f1b510bfc3ed9e306ec8701/exam/exam-7 -------------------------------------------------------------------------------- /exam/exam-7.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char** argv) 4 | { 5 | int x = 0; 6 | int y = 0; 7 | 8 | if (x++ && y++) 9 | { 10 | y += 2; 11 | } 12 | 13 | std::cout << x + y << std::endl; 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /exam/exam-8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rougier/CPP-Crash-Course/9c975863975028b61f1b510bfc3ed9e306ec8701/exam/exam-8 -------------------------------------------------------------------------------- /exam/exam-8.cc: -------------------------------------------------------------------------------- 1 | struct A 2 | { 3 | A(int x) : n(x) {} 4 | int n; 5 | }; 6 | 7 | int main(int argc, char** argv) 8 | { 9 | // A a1; 10 | A a2(2); 11 | // A a3(a2); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /exam/exam-9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rougier/CPP-Crash-Course/9c975863975028b61f1b510bfc3ed9e306ec8701/exam/exam-9 -------------------------------------------------------------------------------- /exam/exam-9.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char** argv) 4 | { 5 | long x[50]; 6 | // A // memset(x, 0, 50); 7 | // B // memset(x, 0, sizeof(x)); 8 | // C // memset(x, 0, 50 * 4); 9 | // D // memset(x, 0, 50 * sizeof(x)); 10 | 11 | std::cout << "sizeof(x): " << sizeof(x) << std::endl; 12 | memset(x, 0, sizeof(x)); 13 | } 14 | -------------------------------------------------------------------------------- /page.tmpl: -------------------------------------------------------------------------------- 1 | %(head_prefix)s 2 | %(head)s 3 | %(stylesheet)s 4 | %(body_prefix)s 5 | %(body_pre_docinfo)s 6 | %(docinfo)s 7 | %(body)s 8 | %(body_suffix)s 9 | -------------------------------------------------------------------------------- /pygment.css: -------------------------------------------------------------------------------- 1 | .hll { background-color: #ffffcc } 2 | .c { font-style: italic } /* Comment */ 3 | .err { border: 1px solid #FF0000 } /* Error */ 4 | .k { font-weight: bold } /* Keyword */ 5 | .cm { font-style: italic } /* Comment.Multiline */ 6 | .c1 { color: #999999; font-style: italic } /* Comment.Single */ 7 | .cs { color: #999999; font-style: italic } /* Comment.Special */ 8 | .ge { font-style: italic } /* Generic.Emph */ 9 | .gh { font-weight: bold } /* Generic.Heading */ 10 | .gp { font-weight: bold } /* Generic.Prompt */ 11 | .gs { font-weight: bold } /* Generic.Strong */ 12 | .gu { font-weight: bold } /* Generic.Subheading */ 13 | .kc { font-weight: bold } /* Keyword.Constant */ 14 | .kd { font-weight: bold } /* Keyword.Declaration */ 15 | .kn { font-weight: bold } /* Keyword.Namespace */ 16 | .kr { font-weight: bold } /* Keyword.Reserved */ 17 | .s { font-style: italic } /* Literal.String */ 18 | .nc { font-weight: bold } /* Name.Class */ 19 | .ni { font-weight: bold } /* Name.Entity */ 20 | .ne { font-weight: bold } /* Name.Exception */ 21 | .nn { font-weight: bold } /* Name.Namespace */ 22 | .nt { font-weight: bold } /* Name.Tag */ 23 | .ow { font-weight: bold } /* Operator.Word */ 24 | .sb { font-style: italic } /* Literal.String.Backtick */ 25 | .sc { font-style: italic } /* Literal.String.Char */ 26 | .sd { font-style: italic } /* Literal.String.Doc */ 27 | .s2 { font-style: italic } /* Literal.String.Double */ 28 | .se { font-weight: bold; font-style: italic } /* Literal.String.Escape */ 29 | .sh { font-style: italic } /* Literal.String.Heredoc */ 30 | .si { font-weight: bold; font-style: italic } /* Literal.String.Interpol */ 31 | .sx { font-style: italic } /* Literal.String.Other */ 32 | .sr { font-style: italic } /* Literal.String.Regex */ 33 | .s1 { font-style: italic } /* Literal.String.Single */ 34 | .ss { font-style: italic } /* Literal.String.Symbol */ 35 | -------------------------------------------------------------------------------- /rst2html.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # coding: utf-8 3 | 4 | # :Author: Georg Brandl; Felix Wiemann; Günter Milde 5 | # :Date: $Date: 2011-08-27 00:23:29 +0200 (Sam, 27. Aug 2011) $ 6 | # :Copyright: This module has been placed in the public domain. 7 | # 8 | # This is a merge of `Using Pygments in ReST documents`_ from the pygments_ 9 | # documentation, and a `proof of concept`_ by Felix Wiemann. 10 | # 11 | # .. class:: borderless 12 | # 13 | # ========== ============================================================= 14 | # 2007-06-01 Removed redundancy from class values. 15 | # 2007-06-04 Merge of successive tokens of same type 16 | # (code taken from pygments.formatters.others). 17 | # 2007-06-05 Separate docutils formatter script 18 | # Use pygments' CSS class names (like the html formatter) 19 | # allowing the use of pygments-produced style sheets. 20 | # 2007-06-07 Merge in the formatting of the parsed tokens 21 | # (misnamed as docutils_formatter) as class DocutilsInterface 22 | # 2007-06-08 Failsave implementation (fallback to a standard literal block 23 | # if pygments not found) 24 | # 2010-11-27 Rename directive from "code-block" to "code". 25 | # Fix fallback if pygments not found. 26 | # Use class-based interface. 27 | # Add "number-lines" option. 28 | # ========== ============================================================= 29 | # 30 | # :: 31 | 32 | """Define and register a code directive using pygments""" 33 | 34 | # Requirements 35 | # ------------ 36 | # :: 37 | 38 | from docutils import nodes 39 | from docutils.parsers.rst import directives, Directive 40 | from docutils.parsers.rst.roles import set_classes 41 | try: 42 | import pygments 43 | from pygments.lexers import get_lexer_by_name 44 | from pygments.formatters.html import _get_ttype_class 45 | with_pygments = True 46 | except ImportError: 47 | with_pygments = False 48 | 49 | # Customisation 50 | # ------------- 51 | # 52 | # Do not insert inline nodes for the following tokens. 53 | # (You could add e.g. Token.Punctuation like ``['', 'p']``.) :: 54 | 55 | unstyled_tokens = [''] # Token.Text 56 | 57 | # Lexer 58 | # --------- 59 | # 60 | # This interface class combines code from 61 | # pygments.formatters.html and pygments.formatters.others. 62 | 63 | class Lexer(object): 64 | """Parse `code` lines and yield "classified" tokens. 65 | 66 | Arguments 67 | 68 | code -- list of source code lines to parse 69 | language -- formal language the code is written in. 70 | 71 | Merge subsequent tokens of the same token-type. 72 | 73 | Iterating over an instance yields the tokens as ``(ttype_class, value)`` 74 | tuples, where `ttype_class` is taken from pygments.token.STANDARD_TYPES 75 | and corresponds to the class argument used in pygments html output. 76 | """ 77 | 78 | def __init__(self, code, language): 79 | """ 80 | Set up a lexical analyzer for `code` in `language`. 81 | """ 82 | self.code = code 83 | self.language = language 84 | self.lexer = None 85 | # get lexical analyzer for `language`: 86 | if language in ('', 'text'): 87 | return 88 | if not with_pygments: 89 | raise ApplicationError('Cannot highlight code. ' 90 | 'Pygments package not found.') 91 | try: 92 | self.lexer = get_lexer_by_name(self.language) 93 | except pygments.util.ClassNotFound: 94 | raise ApplicationError('Cannot highlight code. ' 95 | 'No Pygments lexer found for "%s".' % language) 96 | 97 | # Since version 1.2. (released Jan 01, 2010) Pygments has a 98 | # TokenMergeFilter. ``self.merge(tokens)`` in __iter__ can be 99 | # replaced by ``self.lexer.add_filter('tokenmerge')`` in __init__. 100 | 101 | def merge(self, tokens): 102 | """Merge subsequent tokens of same token-type. 103 | 104 | Also strip the final '\n' (added by pygments). 105 | """ 106 | tokens = iter(tokens) 107 | (lasttype, lastval) = tokens.next() 108 | for ttype, value in tokens: 109 | if ttype is lasttype: 110 | lastval += value 111 | else: 112 | yield(lasttype, lastval) 113 | (lasttype, lastval) = (ttype, value) 114 | if lastval != '\n': 115 | yield(lasttype, lastval) 116 | 117 | def __iter__(self): 118 | """Parse self.code and yield "classified" tokens 119 | """ 120 | codestring = u'\n'.join(self.code) 121 | if self.lexer is None: 122 | yield [('', codestring)] 123 | return 124 | tokens = pygments.lex(codestring, self.lexer) 125 | for ttype, value in self.merge(tokens): 126 | # yield (ttype, value) # token type objects 127 | yield (_get_ttype_class(ttype), value) # short name strings 128 | 129 | 130 | class NumberLines(object): 131 | """Insert linenumber-tokens in front of every newline. 132 | 133 | Arguments 134 | 135 | tokens -- iterable of ``(ttype_class, value)`` tuples 136 | startline -- first line number 137 | endline -- last line number 138 | 139 | Iterating over an instance yields the tokens preceded by 140 | a ``('ln', '')`` token for every line. 141 | Multi-line tokens from pygments are splitted. """ 142 | 143 | def __init__(self, tokens, startline, endline): 144 | self.tokens = tokens 145 | self.startline = startline 146 | # pad linenumbers, e.g. endline == 100 -> fmt_str = '%3d ' 147 | self.fmt_str = '%%%dd ' % len(str(endline)) 148 | 149 | def __iter__(self): 150 | lineno = self.startline 151 | yield ('ln', self.fmt_str % lineno) 152 | for ttype, value in self.tokens: 153 | lines = value.split('\n') 154 | for line in lines[:-1]: 155 | yield (ttype, line + '\n') 156 | lineno += 1 157 | yield ('ln', self.fmt_str % lineno) 158 | yield (ttype, lines[-1]) 159 | 160 | 161 | # CodeBlock directive 162 | # -------------------- 163 | # :: 164 | 165 | class CodeBlock(Directive): 166 | """Parse and mark up content of a code block. 167 | """ 168 | optional_arguments = 1 169 | option_spec = {'class': directives.class_option, 170 | 'name': directives.unchanged, 171 | 'number-lines': directives.unchanged # integer or None 172 | } 173 | has_content = True 174 | 175 | def run(self): 176 | self.assert_has_content() 177 | if self.arguments: 178 | language = self.arguments[0] 179 | else: 180 | language = '' 181 | set_classes(self.options) 182 | classes = ['code', language] 183 | if 'classes' in self.options: 184 | classes.extend(self.options['classes']) 185 | 186 | # TODO: config setting to skip lexical analysis: 187 | ## if document.settings.no_highlight: 188 | ## language = '' 189 | 190 | # set up lexical analyzer 191 | tokens = Lexer(self.content, language) 192 | 193 | if 'number-lines' in self.options: 194 | # optional argument `startline`, defaults to 1 195 | try: 196 | startline = int(self.options['number-lines'] or 1) 197 | except ValueError: 198 | raise self.error(':number-lines: with non-integer start value') 199 | endline = startline + len(self.content) 200 | # add linenumber filter: 201 | tokens = NumberLines(tokens, startline, endline) 202 | 203 | node = nodes.literal_block('\n'.join(self.content), classes=classes) 204 | self.add_name(node) 205 | 206 | # analyze content and add nodes for every token 207 | for cls, value in tokens: 208 | # print (cls, value) 209 | if cls in unstyled_tokens: 210 | # insert as Text to decrease the verbosity of the output. 211 | node += nodes.Text(value, value) 212 | else: 213 | node += nodes.inline(value, value, classes=[cls]) 214 | 215 | return [node] 216 | 217 | 218 | # Register Directive 219 | # ------------------ 220 | # :: 221 | 222 | directives.register_directive('code', CodeBlock) 223 | 224 | # .. _doctutils: http://docutils.sf.net/ 225 | # .. _pygments: http://pygments.org/ 226 | # .. _Using Pygments in ReST documents: http://pygments.org/docs/rstdirective/ 227 | # .. _proof of concept: 228 | # http://article.gmane.org/gmane.text.docutils.user/3689 229 | # 230 | # Test output 231 | # ----------- 232 | # 233 | # If called from the command line, call the docutils publisher to render the 234 | # input:: 235 | 236 | if __name__ == '__main__': 237 | from docutils.core import publish_cmdline, default_description 238 | description = 'code-block directive test output' + default_description 239 | try: 240 | import locale 241 | locale.setlocale(locale.LC_ALL, '') 242 | except: 243 | pass 244 | # Uncomment the desired output format: 245 | # publish_cmdline(writer_name='pseudoxml', description=description) 246 | # publish_cmdline(writer_name='xml', description=description) 247 | publish_cmdline(writer_name='html', description=description) 248 | # publish_cmdline(writer_name='latex', description=description) 249 | -------------------------------------------------------------------------------- /sources/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rougier/CPP-Crash-Course/9c975863975028b61f1b510bfc3ed9e306ec8701/sources/.DS_Store -------------------------------------------------------------------------------- /sources/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2012 Nicolas P. Rougier 2 | # 3 | # This program is free software: you can redistribute it and/or modify it under 4 | # the terms of the GNU General Public License as published by the Free Software 5 | # Foundation, either version 3 of the License, or (at your option) any later 6 | # version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but WITHOUT 9 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 11 | 12 | # You should have received a copy of the GNU General Public License along with 13 | # this program. If not, see . 14 | PLATFORM = $(shell uname) 15 | CXX = g++ 16 | CXXFLAGS = -Wall -ansi -pedantic 17 | 18 | SOURCES:= $(wildcard *.cc) 19 | TARGETS := $(SOURCES:.cc=) 20 | 21 | all: $(TARGETS) 22 | 23 | 24 | define template 25 | $(1): $(1).cc 26 | @echo "Building $$@... " 27 | @$(CXX) $(1).cc $(CXXFLAGS) -o $$@ 28 | endef 29 | $(foreach target,$(TARGETS),$(eval $(call template,$(target)))) 30 | 31 | clean: 32 | @-rm -f $(TARGETS) 33 | 34 | distclean: clean 35 | @-rm -f *~ 36 | -------------------------------------------------------------------------------- /sources/crash-course-2.1.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Nicolas P. Rougier 3 | * 4 | * This program is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU General Public License as published by the Free Software 6 | * Foundation, either version 3 of the License, or (at your option) any later 7 | * version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with 15 | * this program. If not, see . 16 | */ 17 | int main( int argc, char **argv ) 18 | { 19 | // Pointer to a char 20 | char * p1 = new char; 21 | 22 | // A constant pointer to a char 23 | char * const p2 = p1; 24 | 25 | // A pointer to a constant char 26 | const char * p3 = p1; 27 | 28 | // A constant pointer to a constant char 29 | const char * const p4 = p2; 30 | 31 | // A reference to a char 32 | char & r1 = *p2; 33 | 34 | // A reference to a constant char: 35 | const char & r2 = *p4; 36 | 37 | // To have no warning at compilation for unused variables 38 | if( *p3 == r1 ) { } 39 | if( *p3 == r2 ) { } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /sources/crash-course-2.2.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Nicolas P. Rougier 3 | * 4 | * This program is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU General Public License as published by the Free Software 6 | * Foundation, either version 3 of the License, or (at your option) any later 7 | * version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with 15 | * this program. If not, see . 16 | */ 17 | #include 18 | 19 | int main( int argc, char **argv ) 20 | { 21 | const size_t n = 2; 22 | int **array = new int *[n]; 23 | 24 | for( size_t i=0; i. 16 | */ 17 | #include 18 | 19 | class Point { 20 | public: 21 | Point( void ) : _x(0.0), _y(0.0) { }; 22 | 23 | static Point cartesian( const float x, const float y ) 24 | { return Point( x, y ); } 25 | 26 | static Point polar( const float rho, const float theta ) 27 | { return Point( rho*std::cos(theta), rho*std::sin(theta) ); } 28 | 29 | private: 30 | Point( const float x, const float y ) : _x(x), _y(y) { }; 31 | float _x; 32 | float _y; 33 | }; 34 | 35 | 36 | int main( int argc, char **argv ) 37 | { 38 | Point p1 = Point::cartesian(5.7, 1.2); 39 | Point p2 = Point::polar(5.7, 1.2); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /sources/crash-course-3.4.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Nicolas P. Rougier 3 | * 4 | * This program is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU General Public License as published by the Free Software 6 | * Foundation, either version 3 of the License, or (at your option) any later 7 | * version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with 15 | * this program. If not, see . 16 | */ 17 | #include 18 | #include 19 | 20 | class Point { 21 | public: 22 | Point( void ) : _x(0.0), _y(0.0) { }; 23 | 24 | static Point cartesian( const float x, const float y ) 25 | { return Point( x, y ); } 26 | 27 | static Point polar( const float rho, const float theta ) 28 | { return Point( rho*std::cos(theta), rho*std::sin(theta) ); } 29 | 30 | friend std::istream & operator >> (std::istream & input, Point & that) 31 | { return input >> that._x >> that._y; } 32 | 33 | friend std::ostream & operator << (std::ostream & output, Point & that) 34 | { return output << "(" << that._x << ", " << that._y << ")"; } 35 | 36 | private: 37 | Point( const float x, const float y ) : _x(x), _y(y) { }; 38 | float _x; 39 | float _y; 40 | }; 41 | 42 | 43 | int main( int argc, char **argv ) 44 | { 45 | Point p; 46 | std::cout << "Enter a new point x y: "; 47 | std::cin >> p; 48 | std::cout << "p = " << p << std::endl; 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /sources/crash-course-3.5.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Nicolas P. Rougier 3 | * 4 | * This program is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU General Public License as published by the Free Software 6 | * Foundation, either version 3 of the License, or (at your option) any later 7 | * version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with 15 | * this program. If not, see . 16 | */ 17 | #include 18 | 19 | class Foo { 20 | public: 21 | Foo ( void ) 22 | { }; 23 | 24 | Foo & method1( void ) 25 | { return *this; } 26 | 27 | void method2( void ) 28 | { } 29 | }; 30 | 31 | 32 | int main( int argc, char **argv ) 33 | { 34 | Foo foo; 35 | foo.method1().method2(); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /sources/crash-course-4.1.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Nicolas P. Rougier 3 | * 4 | * This program is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU General Public License as published by the Free Software 6 | * Foundation, either version 3 of the License, or (at your option) any later 7 | * version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with 15 | * this program. If not, see . 16 | */ 17 | #include 18 | 19 | class Foo { 20 | public: 21 | Foo( void ) 22 | { std::cout << "Foo constructor called" << std::endl;}; 23 | 24 | virtual ~Foo( void ) 25 | { std::cout << "Foo destructor called" << std::endl;}; 26 | }; 27 | 28 | class Bar : public Foo { 29 | public: 30 | Bar( void ) 31 | { std::cout << "Bar constructor called" << std::endl;}; 32 | 33 | ~Bar( void ) 34 | { std::cout << "Bar destructor called" << std::endl;}; 35 | }; 36 | 37 | int main( int argc, char **argv ) 38 | { 39 | Foo * foo = new Bar(); 40 | delete foo; 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /sources/crash-course-4.2.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Nicolas P. Rougier 3 | * 4 | * This program is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU General Public License as published by the Free Software 6 | * Foundation, either version 3 of the License, or (at your option) any later 7 | * version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with 15 | * this program. If not, see . 16 | */ 17 | #include 18 | 19 | void foo( void ) 20 | { std::cout << "::foo() called" << std::endl;} 21 | 22 | class Foo { 23 | public: 24 | Foo( void ) 25 | { ::foo(); foo(); } 26 | 27 | void foo( void ) 28 | { std::cout << "Foo::foo() called" << std::endl;}; 29 | 30 | }; 31 | 32 | int main( int argc, char **argv ) 33 | { 34 | Foo foo; 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /sources/crash-course-4.3.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Nicolas P. Rougier 3 | * 4 | * This program is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU General Public License as published by the Free Software 6 | * Foundation, either version 3 of the License, or (at your option) any later 7 | * version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with 15 | * this program. If not, see . 16 | */ 17 | #include 18 | #include 19 | 20 | 21 | class Real { 22 | public: 23 | Real( float value = 0 ) : _value(value) { }; 24 | virtual Real operator+(Real &other) { return Real(_value + other._value); } 25 | virtual Real operator-(Real &other) { return Real(_value - other._value); } 26 | virtual Real operator*(Real &other) { return Real(_value * other._value); } 27 | virtual Real operator/(Real &other) { return Real(_value / other._value); } 28 | friend std::ostream& operator<< ( std::ostream& output, Real const & that ) 29 | { return output << that._value; } 30 | protected: 31 | float _value; 32 | }; 33 | 34 | class Integer : public Real { 35 | public: 36 | Integer( int value = 0 ) : Real(int(round(value))) { }; 37 | protected: 38 | int _value; 39 | }; 40 | 41 | 42 | 43 | int main( int argc, char **argv ) 44 | { 45 | Real r1(1.23), r2(4.56); 46 | Integer i1(1), i2(2); 47 | 48 | std::cout << i1+i2 << " " << std::endl; 49 | std::cout << r1+r2 << " " << std::endl; 50 | std::cout << r1+i2 << " " << std::endl; 51 | std::cout << i1+r2 << " " << std::endl; 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /sources/crash-course-4.4.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Nicolas P. Rougier 3 | * 4 | * This program is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU General Public License as published by the Free Software 6 | * Foundation, either version 3 of the License, or (at your option) any later 7 | * version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with 15 | * this program. If not, see . 16 | */ 17 | #include 18 | 19 | class Singleton 20 | { 21 | 22 | public: 23 | static Singleton * instance( void ) 24 | { 25 | if( !_instance ) 26 | { 27 | _instance = new Singleton; 28 | } 29 | return _instance; 30 | } 31 | 32 | private: 33 | Singleton( void ) 34 | { }; 35 | 36 | Singleton( Singleton const & other ) 37 | { }; 38 | 39 | Singleton & operator=( Singleton const & other ) 40 | { 41 | return *this; 42 | }; 43 | 44 | static Singleton* _instance; 45 | }; 46 | 47 | Singleton *Singleton::_instance = 0; 48 | 49 | int main( int argc, char **argv ) 50 | { 51 | Singleton *singleton = Singleton::instance(); 52 | 53 | delete singleton; 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /sources/crash-course-4.5.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Nicolas P. Rougier 3 | * 4 | * This program is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU General Public License as published by the Free Software 6 | * Foundation, either version 3 of the License, or (at your option) any later 7 | * version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with 15 | * this program. If not, see . 16 | */ 17 | #include 18 | 19 | class Functor 20 | { 21 | int _value; 22 | public: 23 | Functor( const int value ) : _value( value ) { } 24 | int operator()( const int value ) { return _value+value; } 25 | }; 26 | 27 | int main( int argc, char **argv ) 28 | { 29 | Functor functor(1); 30 | std::cout << "functor(3) = " << functor(3) << std::endl; 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /sources/crash-course-5.1.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Nicolas P. Rougier 3 | * 4 | * This program is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU General Public License as published by the Free Software 6 | * Foundation, either version 3 of the License, or (at your option) any later 7 | * version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with 15 | * this program. If not, see . 16 | */ 17 | #include 18 | #include 19 | 20 | class FooException : public std::runtime_error { 21 | public: 22 | FooException( void ) : std::runtime_error("FooException") 23 | { } 24 | }; 25 | 26 | class Foo { 27 | public: 28 | Foo( void ) 29 | { throw new FooException; } 30 | }; 31 | 32 | int main( int argc, char **argv ) 33 | { 34 | Foo *foo = new Foo; 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /sources/crash-course-5.2.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Nicolas P. Rougier 3 | * 4 | * This program is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU General Public License as published by the Free Software 6 | * Foundation, either version 3 of the License, or (at your option) any later 7 | * version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with 15 | * this program. If not, see . 16 | */ 17 | #include 18 | #include 19 | #include 20 | 21 | class Foo 22 | { virtual void method( void ) { } }; 23 | 24 | class Bar : public Foo 25 | { }; 26 | 27 | void unexpected( void ) 28 | { throw; } 29 | 30 | void function( void ) throw( int, std::bad_exception ) 31 | { throw 'x'; } 32 | 33 | 34 | int main( int argc, char **argv ) 35 | { 36 | 37 | // Bad alloc 38 | try 39 | { 40 | int * array = new int[-1]; 41 | int i = 0; 42 | i = array[0]; 43 | } 44 | catch( std::bad_alloc & e ) 45 | { 46 | std::cerr << "bad_alloc caught: " << e.what() << std::endl; 47 | } 48 | 49 | // Bad cast 50 | try 51 | { 52 | Foo f; 53 | Bar & b = dynamic_cast( f ); 54 | } 55 | catch( std::bad_cast & e ) 56 | { 57 | std::cerr << "bad_cast caught: " << e.what() << std::endl; 58 | } 59 | 60 | // Bad exception 61 | std::set_unexpected( unexpected ); 62 | try { 63 | function(); 64 | } 65 | catch( int ) 66 | { 67 | std::cerr << "caught int" << std::endl; 68 | } 69 | catch( std::bad_exception e ) 70 | { 71 | std::cerr << "bad_exception caught " << e.what() << std::endl; 72 | } 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /sources/crash-course-5.3.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Nicolas P. Rougier 3 | * 4 | * This program is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU General Public License as published by the Free Software 6 | * Foundation, either version 3 of the License, or (at your option) any later 7 | * version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with 15 | * this program. If not, see . 16 | */ 17 | #include 18 | #include 19 | 20 | class DivideByZero : public std::runtime_error { 21 | public: 22 | DivideByZero( void ) : std::runtime_error("DivideByZero") 23 | { } 24 | }; 25 | 26 | const double divide( const double a, const double b ) 27 | { 28 | if( b == 0 ) 29 | { 30 | throw DivideByZero(); 31 | } 32 | return a/b; 33 | } 34 | 35 | int main( int argc, char **argv ) 36 | { 37 | divide(5,3); 38 | divide(5,0); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /sources/crash-course-5.4.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Nicolas P. Rougier 3 | * 4 | * This program is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU General Public License as published by the Free Software 6 | * Foundation, either version 3 of the License, or (at your option) any later 7 | * version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with 15 | * this program. If not, see . 16 | */ 17 | #include 18 | #include 19 | #include 20 | 21 | struct DivideByZero : public std::runtime_error 22 | { DivideByZero( void ) : std::runtime_error("DivideByZero") { } }; 23 | 24 | struct OverflowError : public std::runtime_error 25 | { OverflowError( void ) : std::runtime_error("OverflowError") { } }; 26 | 27 | struct UnderflowError : public std::runtime_error 28 | { UnderflowError( void ) : std::runtime_error("UnderflowError") { } }; 29 | 30 | 31 | class Integer { 32 | public: 33 | Integer( int value = 0 ) : _value(value) { }; 34 | 35 | virtual Integer operator+(Integer &other) 36 | { 37 | unsigned char result = _value+other._value; 38 | if( result < _value ) 39 | { throw new OverflowError; } 40 | return Integer(result); 41 | } 42 | 43 | virtual Integer operator-(Integer &other) 44 | { 45 | unsigned char result = _value-other._value; 46 | if( result > _value ) 47 | { throw new UnderflowError; } 48 | return Integer(result); 49 | } 50 | 51 | virtual Integer operator*(Integer &other) 52 | { 53 | unsigned char result = _value * other._value; 54 | if((_value > 1) and (other._value >1 ) and ( result < _value )) 55 | { throw new OverflowError; } 56 | return Integer(result); 57 | } 58 | 59 | virtual Integer operator/(Integer &other) 60 | { 61 | if( other._value == 0 ) 62 | { throw new DivideByZero; } 63 | 64 | return Integer(_value / other._value); 65 | } 66 | 67 | friend std::ostream& operator<< ( std::ostream& output, Integer const & that ) 68 | { return output << that._value; } 69 | protected: 70 | unsigned char _value; 71 | }; 72 | 73 | int main( int argc, char **argv ) 74 | { 75 | Integer a(129), b(128), zero(0); 76 | 77 | Integer c(a+b); // overflow 78 | Integer c(b-a); // underflow 79 | Integer c(a/zeor); // divide by zero 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /stylesheet.css: -------------------------------------------------------------------------------- 1 | @import url("pygment.css"); 2 | 3 | pre.code { 4 | margin: 0; 5 | margin-left: 20px; 6 | padding: 10px; 7 | line-height: 1.1em; 8 | background-color: #f9f9f9; 9 | border: 1px solid #ccc; 10 | display:inline-block; 11 | min-width: 50%; 12 | } 13 | 14 | body { 15 | font-family: sans-serif; 16 | width: 1000px; 17 | padding: 10px; 18 | margin: 0 auto; 19 | font-size: 1.0em; 20 | line-height: 1.25em; 21 | color: #282828; 22 | 23 | } 24 | 25 | a { 26 | color: purple; 27 | text-decoration: none; 28 | } 29 | 30 | h1, h2, h3 { 31 | font-family: "Gill Sans", "Trebuchet MS", Calibri, sans-serif; 32 | font-weight: 400; 33 | } 34 | 35 | 36 | h1 { 37 | font-family: "Gill Sans", "Trebuchet MS", Calibri, sans-serif; 38 | font-size: 150%; 39 | font-weight: 400; 40 | color: #fff; 41 | background-color: #bbbbff; 42 | line-height: 1.em; 43 | padding: 8px; 44 | border-radius: 5px; 45 | margin-top: 3em; 46 | } 47 | 48 | h1.title { 49 | margin-top: 1em; 50 | margin-bottom: 0em; 51 | font-size: 250%; 52 | color: #000000; 53 | background: #ffffff; 54 | border-radius: 0; 55 | } 56 | 57 | h2 { 58 | font-family: "Gill Sans", "Trebuchet MS", Calibri, sans-serif; 59 | font-size: 125%; 60 | font-weight: 400; 61 | border-left: 5px solid #ddddff; 62 | line-height: 1.em; 63 | padding: 4px; 64 | } 65 | 66 | th { 67 | text-align:left; 68 | padding-right: .5em; 69 | padding-left: .5em; 70 | } --------------------------------------------------------------------------------