From: GeertVc on
Hi,

I have the following piece of code:

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

using namespace std;

class Shape
{
public:
virtual void draw(){cout << "Drawing a shhape\n"; };
};

class Triangle : public Shape
{
public:
void draw()
{
static int counter = 0;
cout << "Drawing a trngle number " << counter++ << " from " <<
this << endl;
}
};

class Square : public Shape
{
public:
void draw()
{
static int counter = 0;
cout << "Drawing a square number " << counter++ << " from " <<
this << endl;
}
};

int main()
{
vector<Shape*> shapes;
Triangle t1,t2;
Square s1, s2;
shapes.push_back(&t1);
shapes.push_back(&s1);
shapes.push_back(&t2);
shapes.push_back(&s2);

cout << endl;
cout << endl;
for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
cout << endl;
for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
cout << endl;
for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
cout << endl;
for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
cout << endl;
for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
cout << endl;
cout << endl;
}

The original example code was found here:
http://www-h.eng.cam.ac.uk/help/tpl/languages/C++/mem_fun.html

I've done some minor adaptations to understand the principle.

This is the output of the program:

[root(a)axis-00408c012351 /domotics]2595# ./main


Drawing a trngle number 0 from 0x9ff0be7f
Drawing a square number 0 from 0x9ff0be77
Drawing a trngle number 1 from 0x9ff0be7b
Drawing a square number 1 from 0x9ff0be73

Drawing a trngle number 2 from 0x9ff0be7f
Drawing a square number 2 from 0x9ff0be77
Drawing a trngle number 3 from 0x9ff0be7b
Drawing a square number 3 from 0x9ff0be73

Drawing a trngle number 4 from 0x9ff0be7f
Drawing a square number 4 from 0x9ff0be77
Drawing a trngle number 5 from 0x9ff0be7b
Drawing a square number 5 from 0x9ff0be73

Drawing a trngle number 6 from 0x9ff0be7f
Drawing a square number 6 from 0x9ff0be77
Drawing a trngle number 7 from 0x9ff0be7b
Drawing a square number 7 from 0x9ff0be73

Drawing a trngle number 8 from 0x9ff0be7f
Drawing a square number 8 from 0x9ff0be77
Drawing a trngle number 9 from 0x9ff0be7b
Drawing a square number 9 from 0x9ff0be73


One can clearly see the polymorphism mechanism is working fine.
However, I was expecting the following output:

[root(a)axis-00408c012351 /domotics]2595# ./main


Drawing a trngle number 0 from 0x9ff0be7f
Drawing a square number 0 from 0x9ff0be77
Drawing a trngle number 0 from 0x9ff0be7b
Drawing a square number 0 from 0x9ff0be73

Drawing a trngle number 1 from 0x9ff0be7f
Drawing a square number 1 from 0x9ff0be77
Drawing a trngle number 1 from 0x9ff0be7b
Drawing a square number 1 from 0x9ff0be73

Drawing a trngle number 2 from 0x9ff0be7f
Drawing a square number 2 from 0x9ff0be77
Drawing a trngle number 2 from 0x9ff0be7b
Drawing a square number 2 from 0x9ff0be73

Drawing a trngle number 3 from 0x9ff0be7f
Drawing a square number 3 from 0x9ff0be77
Drawing a trngle number 3 from 0x9ff0be7b
Drawing a square number 3 from 0x9ff0be73

Drawing a trngle number 4 from 0x9ff0be7f
Drawing a square number 4 from 0x9ff0be77
Drawing a trngle number 4 from 0x9ff0be7b
Drawing a square number 4 from 0x9ff0be73

Why? Since there's each time two instances of the same class created
(two of class triangle and two of class square), I was expecting that
each "for_each" loop was going to call the "draw()" function *of every
object*, not *of every class*.
One can clearly see the different objects that are called (shown by
the "this" value of the object), but I can only conclude that for
objects of the same class, the "draw" function called is always the
same.
Otherwise, I can't explain why the following happens:

Drawing a trngle number 0 from 0x9ff0be7f
Drawing a square number 0 from 0x9ff0be77
Drawing a trngle number 1 from 0x9ff0be7b
Drawing a square number 1 from 0x9ff0be73

There's a static variable in the "draw()" function and that variable
should only increase when calling "draw()" from the same class
instance ("this" value). Now, eg. when triangle object 0x9ff0be7f is
processed, "draw()" is called and the static variable "counter" (which
should belong to "draw()" of object 0x9ff0be7f) is increased.
But when the second triangle object is called (0x9ff0be7b), that same
static variable "counter" which was used with object 0x9ff0be7f, is
again increased.
I was expecting a "counter" variable for function "draw()" of object
0x9ff0be7f and another "counter" variable for function "draw()" of
object 0x9ff0be7b.

Can someone explain this to me, pls?

Best rgds,

--Geert


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Sean Hunt on
On Mar 29, 8:15 am, GeertVc <geert.vancomperno...(a)gmail.com> wrote:
> Hi,
>
> I have the following piece of code:
>
> <snip code>
>
> There's a static variable in the "draw()" function and that variable
> should only increase when calling "draw()" from the same class
> instance ("this" value). Now, eg. when triangle object 0x9ff0be7f is
> processed, "draw()" is called and the static variable "counter" (which
> should belong to "draw()" of object 0x9ff0be7f) is increased.
> But when the second triangle object is called (0x9ff0be7b), that same
> static variable "counter" which was used with object 0x9ff0be7f, is
> again increased.
> I was expecting a "counter" variable for function "draw()" of object
> 0x9ff0be7f and another "counter" variable for function "draw()" of
> object 0x9ff0be7b.
>
> Can someone explain this to me, pls?
>
> Best rgds,
>
> --Geert

Static variables exist only once per instance of the function. If you
want a variable that's specific to each instance of a given function,
simply use a private member variable instead:

class Triangle : public Shape
{
int counter = 0;
public:
void draw()
{
cout << "Drawing a triangle number " << counter++ << " from " <<
this << endl;
}
};

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: joseph cook on
> There's a static variable in the "draw()" function and that variable
> should only increase when calling "draw()" from the same class
> instance ("this" value). Now, eg. when triangle object 0x9ff0be7f is
> processed, "draw()" is called and the static variable "counter" (which
> should belong to "draw()" of object 0x9ff0be7f) is increased.
> But when the second triangle object is called (0x9ff0be7b), that same
> static variable "counter" which was used with object 0x9ff0be7f, is
> again increased.
> I was expecting a "counter" variable for function "draw()" of object
> 0x9ff0be7f and another "counter" variable for function "draw()" of
> object 0x9ff0be7b.

This is where you are mistaken. scope static objects are 'global' to
all instances of this class.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Mathias Gaunard on
On Mar 29, 3:15 pm, GeertVc <geert.vancomperno...(a)gmail.com> wrote:

> There's a static variable in the "draw()" function and that variable
> should only increase when calling "draw()" from the same class
> instance ("this" value).

No it should not.
That would be the case if your counter was a class member, but it is a
static variable. It is shared by all instances.



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: d04rp on

> Hi,
>
> I have the following piece of code:
>
> #include <iostream>
> #include <vector>
> #include <functional>
>
> using namespace std;
>
> class Shape
> {
> public:
> virtual void draw(){cout << "Drawing a shhape\n"; };
>
> };
>
> class Triangle : public Shape
> {
> public:
> void draw()
> {
> static int counter = 0;
> cout << "Drawing a trngle number " << counter++ << " from " <<
> this << endl;
> }
>
> };
>
> class Square : public Shape
> {
> public:
> void draw()
> {
> static int counter = 0;
> cout << "Drawing a square number " << counter++ << " from " <<
> this << endl;
> }
>
> };
>
> int main()
> {
> vector<Shape*> shapes;
> Triangle t1,t2;
> Square s1, s2;
> shapes.push_back(&t1);
> shapes.push_back(&s1);
> shapes.push_back(&t2);
> shapes.push_back(&s2);
>
> cout << endl;
> cout << endl;
> for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
> cout << endl;
> for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
> cout << endl;
> for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
> cout << endl;
> for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
> cout << endl;
> for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
> cout << endl;
> cout << endl;
>
> }
>
> The original example code was found here:http://www-h.eng.cam.ac.uk/help/tpl/languages/C++/mem_fun.html
>
> I've done some minor adaptations to understand the principle.
>
> This is the output of the program:
>
> [root(a)axis-00408c012351 /domotics]2595# ./main
>
> Drawing a trngle number 0 from 0x9ff0be7f
> Drawing a square number 0 from 0x9ff0be77
> Drawing a trngle number 1 from 0x9ff0be7b
> Drawing a square number 1 from 0x9ff0be73
>
> Drawing a trngle number 2 from 0x9ff0be7f
> Drawing a square number 2 from 0x9ff0be77
> Drawing a trngle number 3 from 0x9ff0be7b
> Drawing a square number 3 from 0x9ff0be73
>
> Drawing a trngle number 4 from 0x9ff0be7f
> Drawing a square number 4 from 0x9ff0be77
> Drawing a trngle number 5 from 0x9ff0be7b
> Drawing a square number 5 from 0x9ff0be73
>
> Drawing a trngle number 6 from 0x9ff0be7f
> Drawing a square number 6 from 0x9ff0be77
> Drawing a trngle number 7 from 0x9ff0be7b
> Drawing a square number 7 from 0x9ff0be73
>
> Drawing a trngle number 8 from 0x9ff0be7f
> Drawing a square number 8 from 0x9ff0be77
> Drawing a trngle number 9 from 0x9ff0be7b
> Drawing a square number 9 from 0x9ff0be73
>
> One can clearly see the polymorphism mechanism is working fine.
> However, I was expecting the following output:
>
> [root(a)axis-00408c012351 /domotics]2595# ./main
>
> Drawing a trngle number 0 from 0x9ff0be7f
> Drawing a square number 0 from 0x9ff0be77
> Drawing a trngle number 0 from 0x9ff0be7b
> Drawing a square number 0 from 0x9ff0be73
>
> Drawing a trngle number 1 from 0x9ff0be7f
> Drawing a square number 1 from 0x9ff0be77
> Drawing a trngle number 1 from 0x9ff0be7b
> Drawing a square number 1 from 0x9ff0be73
>
> Drawing a trngle number 2 from 0x9ff0be7f
> Drawing a square number 2 from 0x9ff0be77
> Drawing a trngle number 2 from 0x9ff0be7b
> Drawing a square number 2 from 0x9ff0be73
>
> Drawing a trngle number 3 from 0x9ff0be7f
> Drawing a square number 3 from 0x9ff0be77
> Drawing a trngle number 3 from 0x9ff0be7b
> Drawing a square number 3 from 0x9ff0be73
>
> Drawing a trngle number 4 from 0x9ff0be7f
> Drawing a square number 4 from 0x9ff0be77
> Drawing a trngle number 4 from 0x9ff0be7b
> Drawing a square number 4 from 0x9ff0be73
>
> Why?
You are creating local static variables in the two draw functions. A
static variable it _not_ bound the an object. Static means that the
variable doesnt belong to any object (It merely belongs to the class).

Since there's each time two instances of the same class created
> (two of class triangle and two of class square), I was expecting that
> each "for_each" loop was going to call the "draw()" function *of every
> object*, not *of every class*.
> One can clearly see the different objects that are called (shown by
> the "this" value of the object), but I can only conclude that for
> objects of the same class, the "draw" function called is always the
> same.
> Otherwise, I can't explain why the following happens:
>
> Drawing a trngle number 0 from 0x9ff0be7f
> Drawing a square number 0 from 0x9ff0be77
> Drawing a trngle number 1 from 0x9ff0be7b
> Drawing a square number 1 from 0x9ff0be73
>
> There's a static variable in the "draw()" function and that variable
> should only increase when calling "draw()" from the same class
> instance ("this" value). Now, eg. when triangle object 0x9ff0be7f is
> processed, "draw()" is called and the static variable "counter" (which
> should belong to "draw()" of object 0x9ff0be7f) is increased.
> But when the second triangle object is called (0x9ff0be7b), that same
> static variable "counter" which was used with object 0x9ff0be7f, is
> again increased.
> I was expecting a "counter" variable for function "draw()" of object
> 0x9ff0be7f and another "counter" variable for function "draw()" of
> object 0x9ff0be7b.

No. the same draw function is used for t1 and t2 and analogous for s1
and s2.
(For the curious one: The first argument to a member function is an
implitis this pointer. (This must explicitly be taken care of in eg.
perl.)

)

HTH Roger Schildmeijer


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]