mardi 2 octobre 2012

A Simple polymorphism example...

It seems that the term "Polymorphism" is not so clear that it should to some of team member (and sometimes it also a mess to me to understand object design we made !!!)... So every time, every time i will use polymorphism in my own work, i will try to extract a demonstration/example.

Let's start with the following example in which we can show that we can define a function to call the f function of a 'Base' object, but accessing finally the f function implemented by the child....


class A
{
public:
  virtual void f()
  {
    std::cout << "A::f()" <<std::endl;
  }
};

class B : public A
{
public:
  virtual void f()
  {
    std::cout << "B::f()" << std::endl;
  }
};

class AI : public A
{

};

class BI : public B
{

};

void master_f(A& base_ref)
{
  base_ref.f();
}

int _tmain(int argc, _TCHAR* argv[])
{
  AI oAI;
  BI oBI;

  master_f(oAI);
  master_f(oBI);

 return 0;
}

dimanche 2 septembre 2012

New VS'12 IDE but build with your old compiler.


Visual Studio project allow to configure the set of tool you want use to build.

If you setup on the same platform VS'08, 2010 and 2012, you can use all the recent tools and functionality of the VS IDE, but still use the old compiler, and don't have to deal with all the recent change in C++ standard or in the compiler.
Property box of a C++ project.


vendredi 25 mai 2012

C++11 - for_each, auto, constexpr, the begin & the end...

Auto:

It's a new keyword really usefull to code faster but it can be scary to use as it leads to more flexibility and less readability.

srand(1234);

 auto vector_size = 10;

 std::vector<int> a(vector_size);
 auto b = std::vector<int>(vector_size);

 auto lambda = [](int& i){i = abs(i);};

 std::for_each(begin(a), end(a), lambda);

 for each (auto var in a)
 {
  std::cout << var << ",";
 }
 std::cout << std::endl;

and you can also use 'auto' as return type qualifier.

int foo() { return 5; } 
       auto j = foo();

==>  Allows to avoid typos
BUT i recommend an extensive usage of VisualAssistX to change function or variable signature and unit-test improvements.

ConstExpr:

As you may know, C98 doesn't allow to declare an array with an expression.

// Comment
//constexpr int f() //Maybe available in VS'11 Final ...
//{
// return 5;
//}

const int g()
{
 return 5;
}

void ConstExpressionDemo()
{
 const int vector_size = 10;
 int A[vector_size];

 int B[g()];//C++98 cannot compile
 /*int B[f()];*///C++11 should compile if constexpr available.
 
 return;
}

Visual C++ 11: Not available.

But using the compiler static analysis, the following code couldn't compile.

// Comment
constexpr int f() //shouldn't compile ...
{
 return rand();
}


for_each and for-loop improvement:

C# and modern languages provided tools to easily iterate over list, collection or array. Before C++11 programmers who wants to iterate on containers elements wrote loops like:
const auto vector_size = 10;
std::vector<int> a(vector_size);
srand(1234);
  
auto lambda_random_init = [](int& i){i = rand();};

for (std::vector<int>::iterator it = a.begin() ; it != a.end() ;  ++it)
{
  *it = rand();
}

But now we can use auto, lambda, std::for_each and range base for to provide compact, and elegant code.
As example, with the following code we can dump vector, deque or array, in fact any container containing any kind of object supporting "cout".

template<class T> void cout_container(T _Container)
{
    for each (auto var in _Container)
    {
        std::cout << var << ",";
    }
    std::cout << std::endl;
}

cout_container<std::vector<int>>(a);

in the following example i implemented vector initialization using a lambda and several vector accumulation based on different loop-style.

const auto vector_size = 10;
    std::vector<int> a(vector_size);

    srand(1234);

    auto lambda_random_init = [](int& i){i = rand();};

    //init using begin & end 
    std::for_each(begin(a), end(a), lambda_random_init);

    cout_container<std::vector<int>>(a);

    //for_each with lambda capture by ref and return sum
    int sum_of_elems = std::accumulate(begin(a), end(a), 0);
    std::cout << sum_of_elems << std::endl;

    std::for_each(begin(a), end(a), [&sum_of_elems](int& n){ sum_of_elems += n; }); //only 1 elt by ref
    std::cout << sum_of_elems << std::endl;
    std::for_each(begin(a), end(a), [&](int& n){ sum_of_elems += n; });//all elt by ref
    std::cout << sum_of_elems << std::endl;

    int tmp = 0;
    //std::for_each(begin(a), end(a), [&sum_of_elems](int& n){ sum_of_elems += n; tmp = 0; });//cannot compile as tmp is not in the capture list!!!
    std::for_each(begin(a), end(a), [&sum_of_elems, &tmp](int& n){ sum_of_elems += n; tmp += n; });//target several output captured by value !!!
    std::cout << sum_of_elems << " " << tmp << std::endl;

    for each (int& n : A) 
    {
        sum_of_elems += n;
    }
    std::cout << sum_of_elems << std::endl;

    cout_container<std::vector<int>>(a);;

mercredi 9 mai 2012

C#: prefer LINQ instead of foreach

In this post, i want to focus in LINQ and its advantage on foreach.

In fact, i meet yesterday the following case: i had a list and i would remove some elements matching a criteria.

As you know C# provide a lots of interface like IQueryable, IEnumerable, etc.... And face to my problem i started by using my list as an IEnumerable through a foreach.... so wrong am i.

In fact if you try something like this:

 var collect = new Collection<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 foreach (var x in collect)
 {
    if (x % 2 == 0)
    {
       collect.Remove(x);
    }
 }
You will meet an exception: System.InvalidOperationException :  .... Because you change the collection itself during the enumeration.

But some very simple solutions exists.
1) If the collection is a List of something implementing the IList Interface you can use "RemoveAll"

collect.RemoveAll(x => x % 2 == 0);


2) If your collection doesn't implement IList, you can use the following code:

 foreach (var x in collect.Where(x => x % 2 == 0).ToList())
 {
    collect.Remove(x);
 } 


  As ToList doesn't provide a new object of type List containing only the element we want to remove and we get through this new list.

No more problems !

jeudi 26 avril 2012

Switch from MSTest to NUnit.

Maybe the 1st post of a long series dedicated to the .Net Universe.

Visual Studio (VS) is well known to come with plenty of plugins or project template to create unit-test project.

But sometimes you would change the unit test framework a project used to.

Indeed it's not so easy but please found below several useful tips&tricks to move a MSTest project and code to a NUnit project.

1) Remove the MSTest Framework reference

2) Add nunit.framework instead.

3) Use the following side by side attribute dictionary to replace all MSTest attribute by their equivalent in the NUnit framework.

4) build & load your assembly with nunit... Every should work! IBut...

5) try to start nunit from your VS and now VS claims that there is no test inside!

6) So edit your vcproj file and search for the <ProjectTypeGUID>. If you found 2 GUID inside, goto to this page to lean more about the existing project type and their GUID. Remove the test GUID {3AC096D0-A1C2-E12C-1390-A8335801FDAB}, save, and reload the project.

And... THE END !