Sergey Ostrovsky on 20 Oct 2003 23:21:02 -0400 |
In earlier editions of his book Stroustrup was much closer to real programmers ( or he wanted to be understood ? ). Back then he tried to teach C guys C++. It was explained how things are implemented, and WHY. The picture was complete and logical. Too bad, it's missing now. I realize that compiler technology changed things, and now you can generate code that doesn't insert a VMT pointer in an object, but use "thunks" ( I don't even know what that is ... ), but that model of implementation was perfect in its completeness, and you'd see how the whole thing ticks. [ Hey, Kevin ] Sergey. ----- Original Message ----- From: "Kevin Brosius" <cobra@compuserve.com> To: "PLUG" <plug@lists.phillylinux.org> Sent: Monday, October 20, 2003 10:27 PM Subject: Re:[PLUG] C++/*this > > Hi, long time no post. I have a C++ question, hopefully someone can > > direct me to some good documentation. > > > > I have always understood that the "this" pointer accessible in non-static > > member functions of C++ objects (classes, structs or unions) is actually > > an implicit argument added by the compiler. > > > > Example: > > > > > > void Object::Function(); > > is actually: > > void Object::Function(Object *this); > > > > > > so when you do this: > > Object ob; > > ob.foo(); > > > > > > it can be thought of as: > > Object ob; > > Object::foo(ob); > > > > > > This has always made sense to me. Since there is only one instantiation > > of all member functions of an object, and these functions are not stored > > as a part of the object, the function must have the *this pointer as an > > implicit argument so that the function has access to the object's other > > members. It also makes sense that static member functions, since they > > do not need an object from which they are called, don't get the implicit > > *this pointer (this would defeat the purpose of making the function > > static). > > > > You are closer to correct, I think. I'm less than impressed with > Stroustrup's coverage of implementation details like this, though. (See > comments later.) > > > > > My instructor seems to think otherwise. Here is the explination I > > was given: > > > > All classes, structs and unions contain a *this pointer that > > references itself. The object also contains pointers to the object > > member functions, therefore when calling a member function in an > > object the member function has access to the *this pointer. > > > > I don't see any evidence that objects contain a copy of *this > themselves, from Stroustrup. And really, there's no need. The storage > location for the object is generally equivalent to *this. Think of it > this way, the object address equals *this, for non-static objects. The > compiler/linker tracks storage location, and resolves it at link time. > It's not needed to be a member of the object. > > > > > Example: > > > > > > class Foo { > > private: > > int x; > > > > > > public: > > void setx(int); > > }; > > > > > > Foo::setx(int) is instantiated only once and each object of type > > Foo has a function pointer to setx: > > > > > > Basically, breaking down what he said results in an object > > that "looks" like this: > > > > > > Foo { > > private: > > int x; > > Foo *this; > > > > > > public: > > void (*setx)(int); // this is the pointer to Foo::setx(int); > > }; > > > > > > > > This makes no sense to me. First there is the question of how does the > > function (which is instantiated only once, which I know to be true) know > > which object is "calling" it? Is there a way for a function (any > > function) to "know" what object it was called from other than providing > > it with a pointer to that object? > > > > Furthur, a simple sizeof() test shows that this (the instructor's idea > > of how an object is created and stored) can't be true unless sizeof() > > doesn't return the true size of an object (which would be VERY bad > > especially if you tried to combine a malloc() call to get the required > > memory instead of new). > > > > By using the simple Foo class above, with only one private data member > > (x), and one public member function (void setx(int)), I see that the > > sizeof(Foo) is 4 (which happens to be sizeof(int)). Is my instructor > > full of it or am I missing something here? > > > > If I have it wrong, please someone point me to some documentation that > > shows me exactly how a class' member functions (non-static) "know" which > > object has called them and where they get *this. > > > Well, you might want to think of it from a usage standpoint. I think > you'll find that the functions don't always need a *this pointer. It > depends on the implementation. For example: > > class Foo { > > public: > void print(void) { printf("Hello World"); }; > }; > > If I call an instance of the above, what happens? > > Foo foo; > foo.print(); > > I'd bet most recent compilers don't pass *this for the above case. It's > unneeded for the implementation. > > How about: > > class Foo { > private: > int x; > > > public: > void setx(int a) { x = a; }; > }; > > calling: > > Foo foo; > foo.setx(5); > > Now, in this case I'd bet you are correct, meaning this case behaves > like "setx(*this, 5)". But here's where I think your instructor is > wrong. There's no need for the object to contain the *this pointer. > The compiler can determine the object referred to by the usage. The > 'foo.' refers to the object, tracking the *this value, so to speak. If > it's needed for the function call, to access object members, then the > compiler passes it on call. If not, we don't need to pass the *this > value to the function call. > > Stroustrup says > "In a nonstatic member function, the keyword 'this' is a pointer to > the object for which the function was invoked. In a non-const member > function of class X, the type of 'this' is X*." [2] > It doesn't say a whole lot more about how that is implemented, but I > think it fits the description I gave above, and what you thought was > correct. I suppose it is possible that a larger overhead compiler might > implement what your instructor suggests. Possibly he is familiar with > some early implementation that used table lookup heavily. > > -- > Kevin > > [1] The C++ Programming Language, Special Edition (3rd. ed., Jan 2003). > Bjarne Stroustrup. p.231. > ___________________________________________________________________________ > Philadelphia Linux Users Group -- http://www.phillylinux.org > Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce > General Discussion -- http://lists.phillylinux.org/mailman/listinfo/plug ___________________________________________________________________________ Philadelphia Linux Users Group -- http://www.phillylinux.org Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce General Discussion -- http://lists.phillylinux.org/mailman/listinfo/plug
|
|