|
From: GeertVc on 28 Mar 2008 23:15 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 29 Mar 2008 23:47 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 29 Mar 2008 23:43 > 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 29 Mar 2008 23:48 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 29 Mar 2008 23:43
> 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! ] |