Wednesday, 29 May 2013

C++ 11 ( some important features ) Part3

Hello friends,
            Welcome you all in the C++ 11 Part3. In the Part2 we have discussed about nullptr and enum.
In this part we will learn about range-based for statement and override virtual methods.


Range-based for statement:-
            Syntax: -        for (for-range-declaration :  expression)
                                                Statement
            Range-based for statement executes statement repeatedly for each element in the expression. 

You can use range-based for statements for vector or any other STL sequence whose range is defined by a begin() and end().
The name that is declared in the for-range-declaration portion is local to the for statement and cannot re-declared in the expression or statement.


Let’s check out the following code to know more how to use:-

// range-based-for.cpp
// author: shobhit upadhyaya

#include 
#include 
using namespace std;

int main() 
{
    //array of integer.
    int iarr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    // Range-based for loop to iterate through the array.
    
/* Accessing values using a copy declared as int type */
    for( int i : iarr ) { 
                                     
        cout << i << " ";
    }
    cout << endl;


/* Using auto keyword that causes type inference to be used. */
    for( auto i : iarr ) { 
        cout << i << " ";
    }
    cout << endl;

/*When you want to modify the iarr, one way to use is as follows */
    for( auto &i : iarr ) { // Type inference by reference.
       
        cout << i << " ";
    }
    cout << endl;

/*We can prevent modification with the help of const */
    for( const auto &i : iarr ) { // Type inference by reference.

        cout << i << " ";
    }
    
    cout << endl;
    
    
    // Vector of integer 
    vector v;
    
    for (int i = 0; i < 10; ++i) {
        v.push_back(i);
    }

    for( const auto &value : v ) {
        cout << value << " ";
    }
    cout << endl;
}
/**/


Override Virtual methods:-

            In C++ there is no mandatory mechanism to figure it out the overridden virtual method in derived classes.
Virtual keyword is also optional that makes the code bit difficult to understand, you may need to look through the top hierarchy to check if the method is virtual or not.

Let's see some virtual methods error scenarios :-

Scenario 1:-

// author: shobhit upadhyaya

class Base
{
public:
   virtual void func(short) {std::cout << "Base -> func(short)" << std::endl;}
};

class Derived : public Base
{
public:
   virtual void func(int) {std::cout << "Derived -> func(int)" << std::endl;}
};

In the above code Derived::func is supposed to override Base::func. In this case the signature is different , so this became a case of function overloading. In this case it creates another virtual function. If you try to call func() through a pointer to Base it will print Base --> func(short)This is a common problem when user wants to modify the base class.


Scenario 2:-

// author: shobhit upadhyaya
class Base
{
public:
   virtual void func(int) const {std::cout << "Base -> func(int) " << std::endl;}
};

class Derived : public Base
{
public:
   virtual void func(int) {std::cout << "Derived -> func(int)" << std::endl;}
};


In the above code also both func() are overloads not override. If you try to call func() through a pointer to Base it will print Base --> func(int)


Fortunately, C++ 11 has added two identifiers: override and final. 

    override :- we can use override to indicate that a method is suppose to be an override of an base class. 

// author: shobhit upadhyaya
class Base
{
public:
   virtual void func(short) {std::cout << "Base -> func(short)" << std::endl;}
};

class Derived : public Base
{
public:
   virtual void func(int) override {std::cout << "Derived -> func(int)" << std::endl;}
};

When you compile the above code you will get compiler error. Because we have used the override specifier, now the compiler will check the base classes to see if there is a virtual function with this exact signature. And if there is not compiler will indicate an error.

    final :- we can use final to indicate that derived class shall not override a virtual method.

// author: shobhit upadhyaya
class Base
{
public:
   virtual void func(int) {std::cout << "Base -> func(int)" << std::endl;}
};

class Derived : public Base
{
public:
   virtual void func(int) override final {std::cout << "Derived -> func(int)" << std::endl;}
};

class Derived2 : public Derived
{
public:
   virtual void func(int) override {std::cout << "Derived2 -> func(int)" << std::endl;}
};

In the above example, Derived2 class is trying to override func() virtual method. But here we will get compiler error. Because Derived class has used final to prevent further overriding. 




Feel free to give your suggestion and ask question ?
Do not forgot to share it :)