Welcome on OnlyTechy
Header image

Generic Functor

October 20th, 2011 | Posted by Saurabh Gupta in C++ | STL - (0 Comments)

Most of time we used classes and sorts the collection of objects on different member variables.  In these scenarios we have to write different-different Functor with respect to the classes. The following code provides a generic Functor which can be used with any class and can be used easily.

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

template <typename T1,typename T2> class Functor
{
public:

Functor( T1 T2::* t):memPointer(t) {}
bool operator() ( const T2 & obj1, const T2 & obj )
{

return obj1.*memPointer < (obj.*memPointer);

}

T1 T2::* memPointer;
};

struct ABC{

double x;

double y;

};

int main()
{

std::vector<ABC> vec;

ABC ab;

ab.x = 9;

ab.y = 89;

vec.push_back(ab);

ab.x = 10;

ab.y = 10;

vec.push_back(ab);

ab.x = 5;

ab.y = 100;

vec.push_back(ab);

Functor<double,ABC> bb(&ABC::x);

std::sort(vec.begin(),  vec.end(),  bb);

std::vector<ABC>::iterator itr = vec.begin();

for (itr = vec.begin(); itr != vec.end(); ++itr)

std::cout << itr->x <<std::endl;

std::cout <<”——————–”<<std::endl;

Functor<double,ABC> b2(&ABC::y);

std::sort(vec.begin(),  vec.end(),  b2);

for (itr = vec.begin(); itr != vec.end(); ++itr)

std::cout << itr->y <<std::endl;

return 0;

}

Out put:
Sorted on member variable x
9
10
100
Sorted on member variable y
10
10
89

For faster initialization and few type of variables( const and reference) will be only initialize in the initialization list otherwise it will generate the compilation errors.

class ConstError{

public:

ConstError()

{

x = 5;

}

const int x;

};

Error would be as (Visual Studio 2008)

e:\initialization.cpp(42) : error C2758: ‘ConstError::x’ : must be initialized in constructor base/member initializer list

e:\initialization.cpp(47) : see declaration of ‘ConstError::x’

Let see an example. class A have a default, parametrized , copy constructor and assignment operator.

class A

{

public:

A (){

cout << “default constructor A()” <<endl;

}

A (int i): x(i) {

cout << “A(): ” << x <<endl;

}

A (const A &obj) {

x = obj.x;

cout << “Copy constructor A(): ” << x <<endl;

}

A& operator = (const A &obj) {

cout << “A operator = ” <<endl;

x = obj.x;

return *this;

}

int x ;

};

Lets create a class which have A and don’t initialize it in initialization list:

class Test {

public:

Test(A &a1) {

a1 = a;

cout << “Test: ” << endl;

}

A a;

};

int main()

{

A a(9);

Test obj(a);

return 0;

}

The output is:

A(): 9
default constructor A()
A operator =
Test:

———————————————————————————————————————————————–

Now do it in initialization list:

class Test {

public:

Test(A &a1):a(a1) {

cout << “Test: ” << endl;

}

A a;

};

Output is:

A(): 9
Copy constructor A(): 9
Test:

In the initialization list, object initialize itself in list while in other, constructor is called and then assignment operator over it.  Now assume if a class  have many member variables including STL container etc then there would big overhead while creation and in assignment operator.

void swap_ints(int *a, int *b)

{

cout << ” a : ” << *a << ” b : ” << *b << endl;
*a += *b;
cout << ” a : ” << *a << ” b : ” << *b <<endl;
*b = *a- *b;
cout << ” a : ” << *a << ” b : ” << *b <<endl;
*a = *a- *b;
cout << ” a : ” << *a << ” b : ” << *b <<endl;

}

int main()

{

int x = 5;

int y = 6;

swap_ints (&x, &y);

return 0;

}

Out put:

a : 5   b : 6
a : 11  b : 6
a : 11  b : 5
a : 6   b : 5

 

 

  1. Pointer itself  occupy memory (32/64 bit) to store the address pointer while reference object don’t occupy memory but refer to existing object.
  2. Reference object must be initialize at the time of definition while initialization is not mandatory for pointer.
    int  *p;           // no error
    Base &obj;    // get compilation error
  3. Pointer can be NULL but not the reference object.
  4. Address of the pointer can be changed at any time but not the reference object.

MACRO is a pre processor which expands before compilation.

Inline is also behaving the same way but it’s a request to the compiler. Therefore, it not sure whether it work as pre processor or not.  If function has big loops/switch/recursion then compiler ignores the request and treat it as normal function.

Inline is type safe while MACRO is not.

What is Vector?

September 8th, 2011 | Posted by Saurabh Gupta in C++ | STL - (0 Comments)
  1. It’s a container which behaves just like an array in C.
  2. Fast in the linear traversal.
  3. It have continues memory.
  4. Fast insert and removal from bottom.

What is template?

September 8th, 2011 | Posted by Saurabh Gupta in C++ | STL - (0 Comments)

This the C++ features to support the generic types for class and functions. Once declare and use with different type of data types. This is a compile time entity.

What is STL (Standard template library)

It’s a template library which provide the framework (template) to solve most general requirements. Futures are as follows:

  1. Container
  2. Associative Containers
  3. Iterator.
  4. Functor
  5. Adopter.
  6. Algorithm(sort, search etc.)
  7. Allocator
  8. Utility
class Base{
public:
Base(){}
Base(const Base &;obj){ }
Base&operator = (const Base &)
{
cout << “Base operator =” << endl;
return *this;
}
};
class Derived: public Base {
public:
Derived(){}
Derived( const Derived &obj):Base(obj)
{
}
Derived& operator = (const Derived &obj)
{
Base::operator =(obj);
cout << “Derived operator =” << endl;
// x = obj.x; return *this;
}
private: int x;
};
Derived obj;
Derived obj1;
// Assignment operator
obj1 = obj;
Same as base constructor is called from the derived class.
class Base{
public:
Base(){}
Base(const Base &obj){}
};
class Derived: public Base{
public:
Derived(){}
Derived( const Derived &der):Base(der)
{
}
};

If it called by value, copy constructor will be called recursively. Hence, end up with a infinite loop. Now days , compilers gives an error on if passed as by value used in a copy constructor.