History of C++
==============
- Origins:
Assembly -> BCPL -> C -> D
-> C++
Algol -> Algol68 -> Java
Fortran -> Simula67 -> C#
- Timeline:
- Bjarne Stroustrup
- C with Classes 1980
Object-orientation
Constructor/destructor
- C++ since 1983
Multiple inheritance
- Support for generic programming
Generic programming: Aleksey Stepanov 1985
First with MACROs
Template since 1989
Stepanov & Musser: Standard Template Library (STL)
- Exceptions since 1991
ML-style exceptions are part of the type system
- ISO standardisation process since 1991
The Annotated Reference Manual (ARM) (with M. Ellis) 1990
The Design and Evolution of C++ 1994
C++98 ISO/IEC 14882:1998
Misising: hash tables, smart pointers, threading
C++03 minor bugfixes (like std::vector storage)
Boost libraries (www.boost.org) -> TR1
C++11 major language revision
http:
move semantics, lambdas, constexpr, threading, auto
hash tables, smart pointers, etc.
C++14 minor revision
http:
C++17 new major release
- Design goals:
- Type safety
C++ is a statically, strongly typed programming language
The compiler decides the type of all (sub)expression in compile time
In run time: pointers, conversions, Object-oriented constructs
- Resource safety
Not just memory! All resources (files, sockets, locks, etc.)
No garbage collection by def. (but can implement)
Use the RAII (Resource Acquisition Is Initialization) idiom
Most beginner makes resource errors
- Performance
Direct access to HW resources. No virtual machine
High performance trading, phone exchange systems
Low energy cosumption (Mars rover)
- Predictability
Large systems (2-10 million eLoC)
Orthogonal features should work well together
- Learnability, readability
C++11: from expert-friendly to novice-friendly
Compiling, linking, executing
=============================
preprocessing compiling linking executing
header source object library
a.h
b.h -> b.cpp -> b.o ---------|
-----> a./out (b.exe)
e.h | |
f.h -> d.cpp -> d.o ---------| |runtime
| |
g.h -> g.cpp -> g.o | |
h.h -> h.cpp -> h.o -> h.a (h.lib) |
archive |
i.h -> i.cpp -> i.o |
j.h -> j.cpp -> j.o -> j.so (j.dll) --|
shared object
$ cat first.cpp
#include <iostream>
int main()
{
std::cout << "hello world" << std::endl;
return 0;
}
$ g++ first.cpp
$ ./a.out
$ g++ -ansi -pedantic -Wall first.cpp
$ g++ -std=c++11 -ansi -pedantic -Wall first.cpp
$ g++ -std=c++11 -ansi -pedantic -Wall first.cpp -o a.exe
$ g++ -c first.cpp
$ ls
a.o
$ g++ a.o
$ g++ a.c b.c d.o e.a f.so
#include <iostream>
using std::cout;
using std::endl;
int main()
{
cout << "hello world" << endl;
return 0;
}
#include <iostream>
using std::cout, std::endl;
int main()
{
cout << "hello world" << endl;
return 0;
}
$ g++ -std=c++11 -ansi -pedantic -Wall first.cpp
first.cpp:3:16: error: expected ‘;’ before ‘,’ token
first.cpp:3:16: error: expected unqualified-id before ‘,’ token
first.cpp:3:27: error: expected constructor, destructor, or type conversion before ‘;’ token
first.cpp: In function ‘int main()’:
first.cpp:7:28: error: ‘endl’ was not declared in this scope
first.cpp:7:28: note: suggested alternative:
In file included from /usr/include/c++/4.7/iostream:40:0,
from first.cpp:1:
/usr/include/c++/4.7/ostream:562:5: note: ‘std::endl’
#include <iostream>
using namespace std;
int main()
{
cout << "hello world" << endl;
return 0;
}
#include <iostream>
int main()
{
for( int fahr = -100; fahr <= 400; fahr += 20 )
{
std::cout << "fahr = " << fahr
<< ", cels = " << 5/9 * (fahr-32)
<< std::endl;
}
return 0;
}
$ g++ -std=c++11 -ansi -pedantic -Wall fahr2cels.cpp
$ ./a.out
fahr = -100, cels = 0
fahr = -80, cels = 0
fahr = -60, cels = 0
fahr = -40, cels = 0
fahr = -20, cels = 0
fahr = 0, cels = 0
fahr = 20, cels = 0
fahr = 40, cels = 0
fahr = 60, cels = 0
fahr = 80, cels = 0
fahr = 100, cels = 0
fahr = 120, cels = 0
fahr = 140, cels = 0
fahr = 160, cels = 0
fahr = 180, cels = 0
fahr = 200, cels = 0
fahr = 220, cels = 0
fahr = 240, cels = 0
fahr = 260, cels = 0
fahr = 280, cels = 0
fahr = 300, cels = 0
fahr = 320, cels = 0
fahr = 340, cels = 0
fahr = 360, cels = 0
fahr = 380, cels = 0
fahr = 400, cels = 0
#include <iostream>
int main()
{
for( int fahr = -100; fahr <= 400; fahr += 20 )
{
std::cout << "fahr = " << fahr
<< ", cels = " << 5./9. * (fahr-32)
<< std::endl;
}
return 0;
}
$ ./a.out
fahr = -100, cels = -73.3333
fahr = -80, cels = -62.2222
fahr = -60, cels = -51.1111
fahr = -40, cels = -40
fahr = -20, cels = -28.8889
fahr = 0, cels = -17.7778
fahr = 20, cels = -6.66667
fahr = 40, cels = 4.44444
fahr = 60, cels = 15.5556
fahr = 80, cels = 26.6667
fahr = 100, cels = 37.7778
fahr = 120, cels = 48.8889
fahr = 140, cels = 60
fahr = 160, cels = 71.1111
fahr = 180, cels = 82.2222
fahr = 200, cels = 93.3333
fahr = 220, cels = 104.444
fahr = 240, cels = 115.556
fahr = 260, cels = 126.667
fahr = 280, cels = 137.778
fahr = 300, cels = 148.889
fahr = 320, cels = 160
fahr = 340, cels = 171.111
fahr = 360, cels = 182.222
fahr = 380, cels = 193.333
fahr = 400, cels = 204.444
#include <iostream>
#include <iomanip>
int main()
{
for( int fahr = -100; fahr <= 400; fahr += 20 )
{
std::cout << "fahr = " << std::setw(5) << fahr
<< ", cels = " << std::setw(8) << 5./9. * (fahr-32)
<< std::endl;
}
return 0;
}
$ ./a.out
fahr = -100, cels = -73.3333
fahr = -80, cels = -62.2222
fahr = -60, cels = -51.1111
fahr = -40, cels = -40
fahr = -20, cels = -28.8889
fahr = 0, cels = -17.7778
fahr = 20, cels = -6.66667
fahr = 40, cels = 4.44444
fahr = 60, cels = 15.5556
fahr = 80, cels = 26.6667
fahr = 100, cels = 37.7778
fahr = 120, cels = 48.8889
fahr = 140, cels = 60
fahr = 160, cels = 71.1111
fahr = 180, cels = 82.2222
fahr = 200, cels = 93.3333
fahr = 220, cels = 104.444
fahr = 240, cels = 115.556
fahr = 260, cels = 126.667
fahr = 280, cels = 137.778
fahr = 300, cels = 148.889
fahr = 320, cels = 160
fahr = 340, cels = 171.111
fahr = 360, cels = 182.222
fahr = 380, cels = 193.333
fahr = 400, cels = 204.444
#include <iostream>
#include <iomanip>
int main()
{
for( int fahr = -100; fahr <= 400; fahr += 20 )
{
std::cout << "fahr = " << std::setw(4) << fahr
<< ", cels = " << std::fixed << std::setw(7)
<< std::setprecision(2) << 5./9. * (fahr-32)
<< std::endl;
}
return 0;
}
$ ./a.out
fahr = -100, cels = -73.33
fahr = -80, cels = -62.22
fahr = -60, cels = -51.11
fahr = -40, cels = -40.00
fahr = -20, cels = -28.89
fahr = 0, cels = -17.78
fahr = 20, cels = -6.67
fahr = 40, cels = 4.44
fahr = 60, cels = 15.56
fahr = 80, cels = 26.67
fahr = 100, cels = 37.78
fahr = 120, cels = 48.89
fahr = 140, cels = 60.00
fahr = 160, cels = 71.11
fahr = 180, cels = 82.22
fahr = 200, cels = 93.33
fahr = 220, cels = 104.44
fahr = 240, cels = 115.56
fahr = 260, cels = 126.67
fahr = 280, cels = 137.78
fahr = 300, cels = 148.89
fahr = 320, cels = 160.00
fahr = 340, cels = 171.11
fahr = 360, cels = 182.22
fahr = 380, cels = 193.33
fahr = 400, cels = 204.44
#include <iostream>
#include <iomanip>
const int lower = -100;
const int upper = 400;
const int step = 40;
int main()
{
for( int fahr = lower; fahr <= upper; fahr += step )
{
std::cout << "fahr = " << std::setw(4) << fahr
<< ", cels = " << std::fixed << std::setw(7)
<< std::setprecision(2) << 5./9. * (fahr-32)
<< std::endl;
}
return 0;
}
#include <iostream>
#include <iomanip>
const int lower = -100;
const int upper = 400;
const int step = 20;
double fahr2cels(double);
int main()
{
for( int fahr = lower; fahr <= upper; fahr += step )
{
std::cout << "fahr = " << std::setw(4) << fahr
<< ", cels = " << std::fixed << std::setw(7)
<< std::setprecision(2)
<< fahr2cels(fahr)
<< std::endl;
}
return 0;
}
double fahr2cels(double f)
{
return 5./9. * (f-32);
}
double fahr2cels( double f);
#include "meteo.h"
double fahr2cels(double f)
{
return 5./9. * (f-32);
}
#include <iostream>
#include <iomanip>
#include "meteo.h"
const int lower = -100;
const int upper = 400;
const int step = 20;
int main()
{
for( int fahr = lower; fahr <= upper; fahr += step )
{
std::cout << "fahr = " << std::setw(4) << fahr
<< ", cels = " << std::fixed << std::setw(7)
<< std::setprecision(2)
<< fahr2cels(fahr)
<< std::endl;
}
return 0;
}
$ g++ -std=c++11 -ansi -pedantic -Wall fahr2cels.cpp
/tmp/ccijFVjc.o: In function `main':
fahr2cels.cpp:(.text+0x21): undefined reference to `fahr2cels(double)'
collect2: error: ld returned 1 exit status
$ g++ -std=c++11 -ansi -pedantic -Wall -c meteo.cpp
$ g++ -std=c++11 -ansi -pedantic -Wall -c fahr2cels.cpp
$ g++ -std=c++11 -ansi -pedantic -Wall meteo.o fahr2cels.o
$ ./a.out
Homework:
1. Create a program printing your name. Compile, link, run.
2. Separate the program to 2 sources: one return the name, other prints
Hints:
- use std::string class to hold your name.
- std::string class is implemented in <string> header.
- there is an automatic conversion from "c-style-strings" to std::string.