Accessing private member functions

H

harry

Hi ppl

I have a question about memory layout of a class. Consider the code
below:

class Base1 {
virtual void f() { cout << "Base1::f" << endl; }
virtual void g() { cout << "Base1::g" << endl; }
};
class Drive : public Base1{
public:
virtual void fd() { cout << "Drive::fd" << endl; }
virtual void gd() { cout << "Drive::gd" << endl; }
};
typedef void(*Fun)(void);
int main() {
Drive objDrive;
Fun pFun = NULL;

int *temp1=(int*)&objDrive+0;
int *temp2=(int*)(*temp1);
pFun=(Fun)((int*)*(temp2+0));
pFun();

temp1=(int*)&objDrive+0;
temp2=(int*)(*temp1);
int *temp3 = (int*)*(temp2+1);
pFun=(Fun)temp3;
pFun();

return 0;
}
This outputs:

Base1::f
Base1::g

This is understandable because of the VPTR and VTable being created
when the derived class object is made. Note that though the virtual
function was private to base class, it can still be called from the
derived class object. Now my question is:

What happens if the base class functions were not virtual but normal
functions? Is there any way we can access the function pointers of
these private member functions from the derived class object?? What is
the memory layout of the derived class object that would be created in
this case?

Thanks in advance
Harry
 
M

mlimber

harry said:
Hi ppl

I have a question about memory layout of a class. Consider the code
below:

class Base1 {
virtual void f() { cout << "Base1::f" << endl; }
virtual void g() { cout << "Base1::g" << endl; }
};
class Drive : public Base1{
public:
virtual void fd() { cout << "Drive::fd" << endl; }
virtual void gd() { cout << "Drive::gd" << endl; }
};
typedef void(*Fun)(void);
int main() {
Drive objDrive;
Fun pFun = NULL;

int *temp1=(int*)&objDrive+0;
int *temp2=(int*)(*temp1);
pFun=(Fun)((int*)*(temp2+0));
pFun();

temp1=(int*)&objDrive+0;
temp2=(int*)(*temp1);
int *temp3 = (int*)*(temp2+1);
pFun=(Fun)temp3;
pFun();

return 0;
}
This outputs:

Base1::f
Base1::g

This is understandable because of the VPTR and VTable being created
when the derived class object is made. Note that though the virtual
function was private to base class, it can still be called from the
derived class object. Now my question is:

What happens if the base class functions were not virtual but normal
functions? Is there any way we can access the function pointers of
these private member functions from the derived class object?? What is
the memory layout of the derived class object that would be created in
this case?

Thanks in advance
Harry

If I saw this in production code and I were your manager, I would
probably have you fired (that is, terminate your employment, not set
you ablaze, although that's not such a bad idea in this case either).

First, you are dealing with a compiler-dependent operation when you try
to access the v-table manually, as noted in the FAQ (e.g.,
http://www.parashift.com/c++-faq-lite/compiler-dependencies.html#faq-38.9).
Second, you are using C-style casts instead of C++ style. Third, you
are writing illegible code. Fourth, your class design is probably
flawed if you need to access private members of a base class. Expand
your interface or add a friend, but do not do what you have done here.

Cheers! --M
 
H

harry

hehe...well...nice mail from a fellow coder(or r u??) who thinks
radically different....ok...i get the fact abt C-style casts but u have
to pardon me for that cos i am a C coder and not a C++ coder. I
disagree with the other 2 points because:

1. I work only with MS compilers and do not have to make products that
would be running in all compilers. And what I have written
is true for MS compilers only. I dont really care abt the other
ones. Plain and Simple.
2. Illegible code?? Illegible code would be if I write something like
this:
pFun = (Fun)*((int*)*(int*)((int*)&objDrive+0)+0);
pFun();
It works fine but I consider this illegible. What I have written is
purely legible. You may have different standards. No comments
henceforth.
3. Well, class design is in front of u. I made a very simple class with
inheritance. If the compiler creates code that lets the developer
access private members (virtual functions. You cannot access any
private data members) thru VTables, I cannot really help it.

Lastly, I would never use such a code for any real time project. But I
dont know whether u have an idea but the whole COM arch is based on
virtual functions and VTables + templates + RPC (for out of proc
servers). I am trying to get under the hood to see how I can juice the
COM arch to the fullest. Given the fact that I am a C coder
(particularly with Windows kernel), I would never venture into COM but
there is still a BIG IF! Hence my quest for knowledge.

Anyway, I would appreciate if someone can give me an idea abt non
virtual members of the base class. It ought to have a function pointer
but can I get hold of it somehow? Is it possible? If neone has tried it
b4 (for fun sake) on ne C++ compiler that exists in this world, I would
be very glad if he/she can share the info.
No hard feelings --M

regards
Harry
 
D

deane_gavin

harry said:
hehe...well...nice mail from a fellow coder(or r u??) who thinks
radically different....ok...i get the fact abt C-style casts but u have
to pardon me for that cos i am a C coder and not a C++ coder. I
disagree with the other 2 points because:

1. I work only with MS compilers and do not have to make products that
would be running in all compilers. And what I have written
is true for MS compilers only. I dont really care abt the other
ones. Plain and Simple.

Then you probably want an MS compiler newsgroup, perhaps one suggested
in

http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.9

since this newsgroup doesn't care about compiler-specific behaviour.

Gavin Deane
 
M

mlimber

Please quote the message you are responding to and place your response
inline or below it. It helps others who are not using Google Groups to
follow the discussion more easily. (To quote a message from Google,
click on "show options" and then click on "Reply" in the revealed
header.)
hehe...well...nice mail from a fellow coder(or r u??)

I am.
who thinks
radically different....ok...i get the fact abt C-style casts but u have
to pardon me for that cos i am a C coder and not a C++ coder. I
disagree with the other 2 points because:

1. I work only with MS compilers and do not have to make products that
would be running in all compilers. And what I have written
is true for MS compilers only. I dont really care abt the other
ones. Plain and Simple.

That's fine, but this newsgroup is for purely *standard* C++. You're
really interested in the Microsoft implementation of virtual tables and
should take your question to microsoft.public.vc.language or some such
forum where they can provide you non-standard advice.
2. Illegible code?? Illegible code would be if I write something like
this:
pFun = (Fun)*((int*)*(int*)((int*)&objDrive+0)+0);
pFun();
It works fine but I consider this illegible. What I have written is
purely legible. You may have different standards. No comments
henceforth.

It is a subjective thing, but I don't think many here would disagree
with my assessment.
3. Well, class design is in front of u. I made a very simple class with
inheritance. If the compiler creates code that lets the developer
access private members (virtual functions. You cannot access any
private data members) thru VTables, I cannot really help it.

But my point stands. You're fighting against the language here. Private
members are intended to be private for a reason, and if you really must
exploit tricks to get around the compiler's facilities for good design
(e.g., private members), then I can only conclude that your design is
flawed and should be changed.
Lastly, I would never use such a code for any real time project.

I never said "real time".
But I
dont know whether u have an idea but the whole COM arch is based on
virtual functions and VTables + templates + RPC (for out of proc
servers).

I do have an idea. :)
I am trying to get under the hood to see how I can juice the
COM arch to the fullest. Given the fact that I am a C coder
(particularly with Windows kernel), I would never venture into COM but
there is still a BIG IF! Hence my quest for knowledge.

"BIG IF". I'm not familiar with the acronym. ;-)
Anyway, I would appreciate if someone can give me an idea abt non
virtual members of the base class. It ought to have a function pointer
but can I get hold of it somehow? Is it possible? If neone has tried it
b4 (for fun sake) on ne C++ compiler that exists in this world, I would
be very glad if he/she can share the info.

The compiler doesn't store function pointers for non-virtual functions.
Rather it converts calls to member functions to ordinary functions.
E.g.,

struct Foo { void Bar( int ); };
Foo foo;
foo->Bar( 42 );

.... becomes something like:

Bar__Foo( foo, 42 );

Thus, you can see that it doesn't need to store pointers to non-virtual
functions since they are really just ordinary functions no different
than, say, std::printf.

That being said, you can get a pointer to a member function quite
simply. Check the FAQ for the details:

http://www.parashift.com/c++-faq-lite/pointers-to-members.html
No hard feelings --M
Ditto.

regards
Harry

Cheers! --M
 
H

harry

Hi

Hope this message would be more readable. Thanks again for the
mail...got the answer. And next time my mail would be on a MS group. I
think that is more suitable to me. Thanks neway

regards
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top