Wednesday, December 5, 2012

Using Algorithm Library and Functional

Just an example to show the utility of the library algorithm.

#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>

using namespace std;

int op_increase (int i) { return ++i; }
int op_sum (int i, int j) { return i+j; }

void inc(int& val){
    static int i = 0;
    val += i;
    i += 10;
}

ostream& operator<<(ostream& out, const vector<int>& a){
    for (int i = 0; i < a.size(); i++)
        out << a[i] << ", ";
    
    out << endl;
    return out;
}
int main () {
  vector<int> first(5);
  vector<int> second;
  vector<int> result;
  
  second.resize(first.size());    
  result.resize(first.size());

  // set some values:
  for_each(first.begin(), first.end(), inc); 
  for_each(second.begin(), second.end(), inc);
  
  cout << first << second << result;

  transform (first.begin(), first.end(), result.begin(), op_increase);
  cout << result;
  
  transform (first.begin(), first.end(), second.begin(), result.begin(), op_sum);
  cout << result;

  vector<int> lenghts;
  vector <string*> numbers;

  // populate vector of pointers:
  numbers.push_back ( new string ("one") );
  numbers.push_back ( new string ("two") );
  numbers.push_back ( new string ("three") );
  numbers.push_back ( new string ("four") );
  numbers.push_back ( new string ("five") );

  lenghts.resize(numbers.size() );

  transform (numbers.begin(), numbers.end(), lenghts.begin(), mem_fun(&string::length) );
  cout << lenghts;

  system("pause");
  return 0;
}

Also, it is possible to use mem_fun_ref instead of mem_fun without the need of use a vector of pointers to strings and just use strings instead of,

Thus, in conclusion, it's very interesting to know how to use this libraries because allow you to work more efficiently and do the same work in less time.

Sunday, December 2, 2012

Pointers, References and Local Variables

Well, I bring here an example when you should figure out how constructors, pointers and reference works.

Thus, here it goes:

Note: Take a fast look to A class and start reading in main function.

#include <iostream>
#include <algorithm>
#include <stdlib.h>

using namespace std;

class A{
private:
    int a;
public:
    A() : a(-1){
        cout << "Default constructor" << endl;
    }
    A(int val) : a(val){
        cout << "Calling contructor by int" << endl;
    }
    //************************************
    A(A* val){
        cout << "Calling contructor by A_pointer" << endl;
        a = val->get();
    }
    A(A& val){
        cout << "Calling contructor by A_reference" << endl;
        a = val.get();
    }

    // This can't be done because when the constructor is called
    // the parameter of the function calls itself, I mean, val is being
    // a local variable
    /*A(A val){
        a = val.get();
    }*/

    int get(){ return a; }
    int get() const { cout << "get 'a' by a const variable\n"; return a; }
    int& getRef(){ return a; }
    //int& getRef() const{ return a; } This can't be done
};


void byPointers(A *a, A *b){
    *a = b->get()*2; //(-1 * 2 = -2)
    // this can be done because a points to a instanced class A
    // in case that would point to null this would be a segmentacion fault
    // on runtime

    // Beside, this calls the constructor by value
}

void byReference(A& a, const A& b){
    a.getRef() = 1000; // we change a_int value, because a is a reference and a.getRef return the atribut inside the class by reference
                       // if the int atribut would've been public that would be equivalent to a.a = 1000;

    //so, because in this call, a and b are A_value, if we change a, also are changing b, let's look:
    cout << b.get() << endl;

    //However, we can't change the b value, because is constant although points to the same variable
}
void byReference2(A& a){
    a.getRef() = 1000000;
}

void byCopy(A a){
    cout << "a: " << a.get() << endl;

    a = A(25); 
    cout << "a: " << a.get() << endl; // now it's 25

    a.getRef() = 26;
    cout << "a: " << a.get() << endl; // now it's 26 but still being
    // a local variable
}

int main(){
    cout << "First example:" << endl;
    A A_value; // this calls default constructor
    
    cout << A_value.get() << endl;
    A* A_pointer; // this doesn't because is a pointer
    A_pointer = &A_value; // this doesn't call any A constructor
    *A_pointer = A_value; // this is equivialent to the previous line
    cout << A_pointer->get() << ", " << (*A_pointer).get() << endl << endl; // point to A_value (two ways to access it)
    //**************************************************************************************

    cout << "Second example:" << endl;
    byPointers(&A_value,&A_value); // this doesn't call any constructor
    // just points to the references of A_value, so inside the function 
    // if we change A *a, A *b pointers we'll change A_value
    cout << endl;

    // This is a bit obfuscated, so peruse
    byCopy(A_value); // byCopy expect to creat (A a) as a local variable
                     // so calls A_reference, or method to copy a class
                     // however, the construtor is by reference, a still be
                     // a local variable
    cout << A_value.get() << endl << endl;// Thus, we haven't changed any attribut of A_value
    //**************************************************************************************
    
    cout << "Third example:" << endl;
    byReference(A_value, A_value); // pass by reference doesn't call any constructor
                                   // because a and b are exactly A_value
    // So, after the call, A_value have changed:
    cout << A_value.get() << endl;

    // even, we can do the same with the pointer
    byReference2(*A_pointer);
    // and because A_pointer points to A_value, this will also change the value
    cout << A_value.get() << endl; 

    system("pause");
    return 0;
}