Thursday 21 January 2016

C++11 new features

auto: Used for type inference

  //For variables
  auto i = 42;        // i is an int
  auto l = 42LL;      // l is an long long
  auto p = new foo(); // p is a foo*
  
  //For iterators
  std::map<std::string, std::vector<int>> map;
  for(auto it = begin(map); it != end(map); ++it) {}

  //For function return types
  template <typename T1, typename T2>
  auto compose(T1 t1, T2 t2) -> decltype(t1 + t2)
  {
     return t1+t2;
  }
  auto v = compose(2, 3.14); // v's type is double


nullptr:

  void display(int a){ cout<<"Integer version called"<<endl; }
  void display(int *p){ cout<<"Int pointer version called"<<endl; }
  void display(long a){ cout<<"long version called"<<endl; }
  int main()
  {
        display(nullptr); //Calls pointer version
        display(NULL); //Calls long version
        display(0); //Calls int version
  } 

range-based for loop:

  string str = "United Online";
  for(char c : str)
      cout<<c;

override:

  - For runtime polymorphism,
1. Signatures of functions must be same in both Base and Derived classes.
2. Base class pointer is used to achieve this.
base * pb = new Derived();
  - But there is a chance that by mistake the function signature is different in both Base and Derived     classes. Unnoticeably, we might be thinking that runtime polymorphism will work and Derived   version will be called. But ideally just compile time polymorphism will happen and Base version will be called.
  - To avoid such bugs, 'override' is introduced. It will error out if function signatures are different.

  class parent {
        public:
          virtual void handle_event(int something) {cout<<"Boring default code"<<endl;}
  };

  class child : public parent {
        public:
                // force handle_event to override a existing function in parent
                // error out if the function with the correct signature does not exist
                virtual void handle_event(int something) override {cout<<"New exciting code"<<endl;}
  };

  int main() {
      parent *p = new child();
      p->handle_event(1);
  }


final:

  - To stop Derived class overriding Base class virtual function.
  - To stop inheriting Base class it self.

enums:

  //Old style (Global scope)
   enum Animals{Cat, Dog, Chicken};
   enum Birds{Eagle, Duck, Chicken}; //Error, Chicken is already used

   //New style (Seperate scope)
   enum class Fruits{Apple, Mango, Orange};
   enum class Colors : char{Red, Green, Orange};//Allowed, Fruits::Orange != Colors::Orange

smart pointers: used for reference counting and auto releasing of owned memory.
  • unique_ptr: should be used when ownership of a memory resource does not have to be shared (it doesn't have a copy constructor), but it can be transferred to another unique_ptr (move constructor exists).
  • shared_ptr: should be used when ownership of a memory resource should be shared (hence the name).
  • weak_ptr: holds a reference to an object managed by a shared_ptr, but does not contribute to the reference count; it is used to break dependency cycles (think of a tree where the parent holds an owning reference (shared_ptr) to its children, but the children also must hold a reference to the parent; if this second reference was also an owning one, a cycle would be created and no object would ever be released).
  On the other hand the auto_ptr is obsolete and should no longer be used.

lambdas: Nothing but anonymous functions

Eg: [](int n){cout<<n<<" ";}

No comments:

Post a Comment