Difference between revisions of "From C++03 to C++11"

From Gridkaschool
m (loops)
(exercises)
Line 167: Line 167:
 
</source>
 
</source>
   
===Override===
+
===override===
 
* You can add override behind the declaration of a function.
 
* You can add override behind the declaration of a function.
 
* Compile, then add override and recompile, see the difference?
 
* Compile, then add override and recompile, see the difference?
Line 257: Line 257:
   
 
</source>
 
</source>
  +
  +
===final===

Revision as of 15:10, 1 September 2014

Gridka School 2014 C++ course

  • Martin Heck, KIT EKP
  • Jörg Meyer, KIT SCC

Literature on C++

C++ books

  • The C++ Programming Language, Bjarne Stroustrup
  • Effective C++, Scott Meyers
  • More Effective C++: 35 New Ways to Improve Your Programs and Designs
  • Modern C++ Design, Andrei Alexandrescu
  • The C++ Standard Library, Nicolai M. Josuttis
  • C++ Templates, David Vanevoorde, Nicolai M. Josuttis
  • Exceptional C++, Herb Sutter
  • More Exceptional C++, Herb Sutter

C++11 books

  • The C++ Programming Language, 4th Edition, Bjarne Stroustrup
  • The C++ Standard Library: A Tutorial and Reference (2nd Edition), Nicolai M. Josuttis
  • C++11 programmieren, Torsten T. Will (German)
  • C++11: Der Leitfaden für Programmierer zum neuen Standard, R. Grimm (German)

C++ links

C++11 links

Technical aspects for the course

Gridka School slides

  • Bug avoidance: The C++11 Standard offers new ways in which the compiler can help you to avoid bugs. Especially the new keywords override, final, and smart pointers.

access to machines

You can run the exercises either on your own computer or ssh to one of our prepared machines using your Gridka School account.

  • connection from Linux/Unix: ssh -p24 <username>@gks-virt<xxx>.scc.kit.edu
  • connection from Windows: use an ssh client like putty, or use cygwin

This is a list of hostnames: gks-virt084 gks-virt088 gks-virt098

compilaton and execution of code

Most examples consist of just one cpp file, i.e. no header file, no additional library. Use the following commands to compile and run the code:

g++ mycode.cpp
./a.out

For C++11 support do:

g++ -std=c++11 mycode.cpp
./a.out

exercises

loops

  • Have a look at the following ways to loop over container elements. Which ones are new, i.e. only work in C++11? Add a range-based for loop.
#include<vector>
#include<iostream>
#include<iterator>     // std::ostream_iterator
#include<algorithm>    // std::for_each   

struct print_int {
  void operator() (int i) {
    std::cout<<i<<'\n';
  }
};

int main() {
   std::vector<int> v{1,4,2,3,4,5,7};

  for (int i=0,N=v.size();i!=N;++i)
    std::cout<<v[i]<<'\n';
  
  for (std::vector<int>::const_iterator it=v.begin();it!=v.end();++it)
    std::cout<<*it<<'\n';

  std::copy(v.begin(),v.end(),std::ostream_iterator<int>(std::cout,"\n"));

  print_int pi;
  std::for_each(v.begin(),v.end(),pi);

  for (auto it=v.cbegin();it!=v.cend();++it)
    std::cout<<*it<<'\n';         

  for (auto it=begin(v);it!=end(v);++it)
    std::cout<<*it<<'\n';         

  std::for_each(v.begin(),v.end(),[](int i){std::cout<<i<<'\n';});

}

smart pointer

  • Add a memory management to the binary search tree by introducing adequate smart pointers.
  • In which order do the nodes get deleted?

binary_tree.hpp

#ifndef BINARY_TREE_HPP
#define BINARY_TREE_HPP

#include<initializer_list>

class binary_tree {
  struct node {
    node(int k): key(k), left(0), \
         right(0), p(0) {}
    int key;
    node *left, right, *p;
  };

public:
  node* root;
  void insert(node* z);
  void inorder_print(node* x);
  binary_tree(std::initializer_list<int> values): root(0) {
    for (auto it=values.begin(); \
      it!=values.end();++it) 
	insert(new node(*it));
  }
};

#endif

binary_tree.cpp

#define BINARY_TREE_CPP
#include<iostream>
#include "binary_tree.hpp"

void binary_tree::insert(node* z) {
    node* y=0;
    node* x=root;
    while (x) {
      y=x;
      if (z->key < x->key) 
	x=x->left;
      else
	x=x->right;    
    }
    z->p = y;
    if (!y)
      root=z; // tree was empty
    else if (z->key < y->key)
      y->left = z;
    else
      y->right = z;
}

void binary_tree::inorder_print(node* x) {
    if (x) {
      inorder_print(x->left);
      std::cout<<x->key<<" ";
      inorder_print(x->right);
    }
}


int main() {
  binary_tree bt{12,5,5,7,2,4};
  bt.inorder_print(bt.root);//2 4 5 5 7 12  
}

override

  • You can add override behind the declaration of a function.
  • Compile, then add override and recompile, see the difference?

INIOverride.cc

#include <iostream>

/** Struct to hold information about cars. 
 *
 *  To have multiple cars of a certain different type, you can inherit from this struct.
 */
struct Car {
    /** Returns a generic estimate of the weight of a car (1 ton), if not overriden.*/
    virtual int getWeightInKg();

    /** Returns a generic estimate of the speed of a car (180), if not overriden.*/
    virtual int getMaxSpeedInKmh() const;
    
    /** Returns a generic estimate of the number of wheels of a car (4), if not overriden.*/
    virtual int getNWheels();
    
    /** Returns a generic estiate of the number of seats in a car (5), if not overrriden.*/
    int getNSeats();
};

/** Struct to use with the bigger and slower Monster Truck spcial car.*/
struct MonsterTruck: public Car {
  /** Monster Trucks are much heavier on average the averge cars (3 tons).*/
  int getWeightInKg();

  /** Monster Trucks are much slower than average cars (80).*/
  int getMaxSpeedInKmh();
    
  /** Monster Trucks have double wheels (--> 8) due to their big weight.*/
  virtual int getNWheels();
  
  /** Monster Trucks have one big front bench with 3 seats.*/
  int getNSeats();
};

int main()
{
  using namespace std;

  MonsterTruck monsterTruck;
  Car& car = monsterTruck;
  cout << "Weight:           " << car.getWeightInKg() << endl;
  cout << "Speed:            " << car.getMaxSpeedInKmh() << endl;
  cout << "Number of Wheels: " << car.getNWheels() << endl;
  cout << "Number of Seats:  " << car.getNSeats() << endl;

  cout << "Once more the Speed: "           << monsterTruck.getMaxSpeedInKmh() << endl;
  cout << "Once more the number of Seats: " << monsterTruck.getNSeats() << endl;
}

//---------------------------------------------------------------------------------

int Car::getWeightInKg(){
  return 1000;
}

int MonsterTruck::getWeightInKg(){
  return 3000;
}

int Car::getMaxSpeedInKmh() const {
  return 180;
}

int MonsterTruck::getMaxSpeedInKmh() {
  return 80;
}

int Car::getNWheels() {
  return 4;
}

int MonsterTruck::getNWheels() {
  return 8;
}

int Car::getNSeats(){
  return 5;
}

int MonsterTruck::getNSeats(){
  return 3;
}

final