Methods of Objects

J

Jon Slaughter

Are methods of a class created only once for all objects or for each object
as its own copy of its methods?

It seems that I can only access an object method's address using :: so if I
have a class with method func and I want its address I would do
&someClass::someFunc which seems to imply that there is only one function
per class(and hence for all instantiations of that class)... when I create a
very large array of objects of that class it seems to back this up as the
file size does not change much...

I just want to be sure that there is no need to deal with static members and
stuff for no to make sure I optimize size if the compiler handles it
automatically(which I hope it does)? i.e. there is virtually no difference
between these two classes


class A
{
int x;
public:
void func(int y) { x = y; }
}

and

class B
{
int x;
public:
static void func(B &b, int y) { b.x = y; }
}


a.func(1);

and

b.func(b, 1);

should produce the exact same code? (or very very close?) I'm hoping that
the compiler internally handles class A as class B or maybe even better. The
reason is that simply class B has only 1 func even if I do something like B
b[10000]; while I'm not sure about class A.. if I do A a[10000] if it
creates 10000 copies of func or not. Though I don't see any reason why this
would happen and all my "tests" say it doesn't... I just want to make sure
so.

Thanks,
Jon
 
T

Thomas Tutone

Jon said:
Are methods of a class created only once for all objects or for each object
as its own copy of its methods?

The former.

[snip]
I just want to be sure that there is no need to deal with static members and
stuff for no to make sure I optimize size if the compiler handles it
automatically(which I hope it does)? i.e. there is virtually no difference
between these two classes


class A
{
int x;
public:
void func(int y) { x = y; }
}

and

class B
{
int x;
public:
static void func(B &b, int y) { b.x = y; }
}

The above implies sizeof(A) == sizeof(B) == sizeof(int). I.e., each
class should be the size of an int.
a.func(1);

and

b.func(b, 1);

should produce the exact same code? (or very very close?)

I expect they would be quite close, but it doesn't matter - the number
of copies of the member function does not increase as objects are
constructed.
I'm hoping that
the compiler internally handles class A as class B or maybe even better. The
reason is that simply class B has only 1 func even if I do something like B
b[10000]; while I'm not sure about class A.. if I do A a[10000] if it
creates 10000 copies of func or not.

It doesn't.

Best regards,

Tom
 
T

Thomas Tutone

Thomas said:
The former.

I should qualify this, I suppose. The code for the class's member
functions does not affect the size of the class, because the code is
not data. However, if you define the member function inline (as you do
in your example), then if the compiler complies with your inlining
request, a new copy of that code is inserted every time you call that
member function. It still has nothing to do with the size of the
constructed object, though, and each object does not have "its own copy
of it" member functions.

Best regards,

Tom
 
I

Ian

Jon said:
Are methods of a class created only once for all objects or for each object
as its own copy of its methods?
Once, the instance of the object is identified by the this pointer.
It seems that I can only access an object method's address using :: so if I
have a class with method func and I want its address I would do
&someClass::someFunc which seems to imply that there is only one function
per class(and hence for all instantiations of that class)... when I create a
very large array of objects of that class it seems to back this up as the
file size does not change much...

I just want to be sure that there is no need to deal with static members and
stuff for no to make sure I optimize size if the compiler handles it
automatically(which I hope it does)? i.e. there is virtually no difference
between these two classes
Note that a pointer to a member function is a different beast from a
pointer to a static member.

Ian
 
J

Jon Slaughter

Ian said:
Once, the instance of the object is identified by the this pointer.

Note that a pointer to a member function is a different beast from a
pointer to a static member.

how so? I thought static functions were identical to global functions as
far as the internal representation was concerned? If there is only one
function, wether static or not, per class then what is the difference?

Thanks,

Jon
 
J

Jon Slaughter

Thomas Tutone said:
I should qualify this, I suppose. The code for the class's member
functions does not affect the size of the class, because the code is
not data. However, if you define the member function inline (as you do
in your example), then if the compiler complies with your inlining
request, a new copy of that code is inserted every time you call that
member function. It still has nothing to do with the size of the
constructed object, though, and each object does not have "its own copy
of it" member functions.

Best regards,

Tom

Ok, as long as the compiler does its best to optimize code and data so that
there is not any wasted space then its ok. Obviously if its inline then one
would increase the code size(but this, I think, is irrespective of the
number of objects but the number of calls to the inline function?).

Just wanted to make sure that in general the number of objects created do
not increase the size proportional to the method code size(obviously it has
to do with the data). It seemed like a logical thing to do and my examples
were only giving the right outcome but i wasn't completely sure if I was
missing something since I wasn't doing a very thorough test.

Thanks,

Jon
 
T

Thomas Tutone

Jon said:
how so? I thought static functions were identical to global functions as
far as the internal representation was concerned?

That's true.
If there is only one
function, wether static or not, per class then what is the difference?

I think Ian means that they involve two different kinds of _pointers_.
Take a look at Section 33 of the FAQ to see the difference:

http://www.parashift.com/c++-faq-lite/pointers-to-members.html

Best regards,

Tom
 
J

Jon Slaughter

Thomas Tutone said:
That's true.


I think Ian means that they involve two different kinds of _pointers_.
Take a look at Section 33 of the FAQ to see the difference:

http://www.parashift.com/c++-faq-lite/pointers-to-members.html

You mean the


a.. Its type is "int (*)(char,float)" if an ordinary function
b.. Its type is "int (Fred::*)(char,float)" if a non-static member
function of class Fred

part?

Seems to me that this only addresses the resolution of the function but
internally they are the same? (just pointers) Its up to the compiler to
determine how those pointers function and there arguments to be placed on
the stack properly, etc...

I mean, as far as I can see its just saying that if I wanted to create a
pointer to a member function I have to use that syntax so the compiler will
"know" but in all actuality its still just a pointer function that the
resolution is just some "meta syntax" that exists in the language to make it
easier to program and keep things encapsulated(i.e. I could write everytin
in C that would produce the "exact" same code that doesn't use classes or
anything but the classes are really just a way to group data and code to
make programming easier but ultimately it pretty much represents the same
machine code in the long run?)?



Best regards,

Tom

Jon
 
I

Ian

Jon said:
You mean the


a.. Its type is "int (*)(char,float)" if an ordinary function
b.. Its type is "int (Fred::*)(char,float)" if a non-static member
function of class Fred

part?

Seems to me that this only addresses the resolution of the function but
internally they are the same? (just pointers) Its up to the compiler to
determine how those pointers function and there arguments to be placed on
the stack properly, etc...
No, they are not. That's what I was trying to say before.

Ian
 
M

Matthias Kaeppler

Jon said:
[...] Obviously if its inline then one
would increase the code size(but this, I think, is irrespective of the
number of objects but the number of calls to the inline function?).

That's right, there's no connection whatsoever between the number of
class /instances/ and the quantity of code produced for operating on
those instances. This code is generated once, for the class itself.
Instances of a class only store state information.
 
K

Karl Heinz Buchegger

Jon said:
I mean, as far as I can see its just saying that if I wanted to create a
pointer to a member function I have to use that syntax so the compiler will
"know" but in all actuality its still just a pointer function that the
resolution is just some "meta syntax" that exists in the language to make it
easier to program and keep things encapsulated(i.e. I could write everytin
in C that would produce the "exact" same code that doesn't use classes or
anything but the classes are really just a way to group data and code to
make programming easier but ultimately it pretty much represents the same
machine code in the long run?)?

You are missing that somehow a member function must be able to identify the
object it is working on. A static function doesn't need to do that, since
it is independent of any object.

So how does a member function identify the object it is working on?
Most compilers do it this way:
They pass a hidden parameter to the function: a pointer to the object.
This pointer becomes the 'this' pointer inside the member function.

So when you do:

class X
{
public:
void foo();

private:
int x;
};

void X::foo()
{
x = 5;
}

then the compiler internally comes up with:

struct X
{
int x;
};

void X_foo( X* pThis )
{
pThis->x = 5;
}

and changes a call to the member function:

int main()
{
X Obj;
Obj.foo();
}

to:

int main()
{
X Obj;

X_foo( &Obj );
}

This should also answer your question if every object needs a seperate
code base. Obviously not. Each function can exist just once. When the
function is called, the address of the object it should work on, is passed
to that function.

But now you can also see, that an ordinary member function cannot have the
same signature then a normal function or a static function. The object it
should work on, must be passed to that function.
 

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,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top