Connecting Tech Pros Worldwide Help | Site Map

Size of an inherited class ?

François Fleuret
Guest
 
Posts: n/a
#1: Mar 13 '06
Dear all,

I fear this is a question which has been asked zillions of
times. However, it seems to me to be such a legitimate feature that I
can't imagine it is impossible.

How can one know the size of an object in a "virtual" manner ?

For instance, how can I write a virtual function print_size(); which
prints the size of *this, and which will print the correct value with
an object of an inherited class ?

Thanks in advance for any hint,

--
François Fleuret http://cvlab.epfl.ch/~fleuret
Michiel.Salters@tomtom.com
Guest
 
Posts: n/a
#2: Mar 13 '06

re: Size of an inherited class ?


François Fleuret wrote:[color=blue]
> Dear all,
>
> I fear this is a question which has been asked zillions of
> times. However, it seems to me to be such a legitimate feature that I
> can't imagine it is impossible.
>
> How can one know the size of an object in a "virtual" manner ?
>
> For instance, how can I write a virtual function print_size(); which
> prints the size of *this, and which will print the correct value with
> an object of an inherited class ?[/color]

You can't, because you can't do anything useful with it. sizeof() is
used to allocate memory for new objects (before you can even call
print_size()) or memcpy existing objects (which you can't do if it has
virtual functions).

What legitimate use did you imagine?

HTH,
Michiel Salters

John Carson
Guest
 
Posts: n/a
#3: Mar 13 '06

re: Size of an inherited class ?


"François Fleuret" <francois.fleuret@epfl.ch> wrote in message
news:8764miy5mb.fsf@fleuret.homeunix.org[color=blue]
> Dear all,
>
> I fear this is a question which has been asked zillions of
> times. However, it seems to me to be such a legitimate feature that I
> can't imagine it is impossible.
>
> How can one know the size of an object in a "virtual" manner ?
>
> For instance, how can I write a virtual function print_size(); which
> prints the size of *this, and which will print the correct value with
> an object of an inherited class ?
>
> Thanks in advance for any hint,
>
> --
> François Fleuret
> http://cvlab.epfl.ch/~fleuret[/color]

This seems to work

#include <iostream>
using namespace std;

struct Base
{
int b;
virtual void Print_Size()
{
cout << sizeof(*this) << endl;
}
};


struct Derived : Base
{
int array[4];
virtual void Print_Size()
{
cout << sizeof(*this) << endl;
}
};

int main(int argc, char* argv[])
{
Base b;
Derived d;

Base * pb1 = &b;
Base * pb2 = &d;

pb1->Print_Size();
pb2->Print_Size();
return 0;
}


--
John Carson


peter koch
Guest
 
Posts: n/a
#4: Mar 13 '06

re: Size of an inherited class ?



Michiel.Salters@tomtom.com skrev:
[color=blue]
> François Fleuret wrote:[color=green]
> > Dear all,
> >
> > I fear this is a question which has been asked zillions of
> > times. However, it seems to me to be such a legitimate feature that I
> > can't imagine it is impossible.
> >
> > How can one know the size of an object in a "virtual" manner ?
> >
> > For instance, how can I write a virtual function print_size(); which
> > prints the size of *this, and which will print the correct value with
> > an object of an inherited class ?[/color]
>
> You can't, because you can't do anything useful with it. sizeof() is
> used to allocate memory for new objects (before you can even call
> print_size()) or memcpy existing objects (which you can't do if it has
> virtual functions).
>
> What legitimate use did you imagine?
>[/color]

It is difficult to find a use for that size, but perhaps some sort of
clone:

class base
{
public:
virtual ~base() = 0;
virtual int size() = 0;
virtual void clone(void* adress) = 0;
};

void silly(base* b)
{
void* clonemem = malloc(b->size());
b->clone(clonemem);
}


/Peter[color=blue]
> HTH,
> Michiel Salters[/color]

François Fleuret
Guest
 
Posts: n/a
#5: Mar 13 '06

re: Size of an inherited class ?


Dear John,

You wrote on 13 Mar 2006 12:51:47 MET:
[color=blue]
> This seems to work
>
> #include <iostream>
> using namespace std;
>
> struct Base
> {
> int b;
> virtual void Print_Size()
> {
> cout << sizeof(*this) << endl;
> }
> };
>
>
> struct Derived : Base
> {
> int array[4];
> virtual void Print_Size()
> {
> cout << sizeof(*this) << endl;
> }
> };
>
> int main(int argc, char* argv[])
> {
> Base b;
> Derived d;
>
> Base * pb1 = &b;
> Base * pb2 = &d;
>
> pb1->Print_Size();
> pb2->Print_Size();
> return 0;
> }[/color]

Yeah, but since sizeof used the static type of the class, you have to
re-write the method Print_Size -- with the exact same code -- in the
derived class.

I was wondering if there was a way to access the information about the
class size from its virtual table.

Cheers,

--
François Fleuret http://cvlab.epfl.ch/~fleuret
Rolf Magnus
Guest
 
Posts: n/a
#6: Mar 13 '06

re: Size of an inherited class ?


François Fleuret wrote:
[color=blue]
> Dear John,
>
> You wrote on 13 Mar 2006 12:51:47 MET:
>[color=green]
>> This seems to work
>>
>> #include <iostream>
>> using namespace std;
>>
>> struct Base
>> {
>> int b;
>> virtual void Print_Size()
>> {
>> cout << sizeof(*this) << endl;
>> }
>> };
>>
>>
>> struct Derived : Base
>> {
>> int array[4];
>> virtual void Print_Size()
>> {
>> cout << sizeof(*this) << endl;
>> }
>> };
>>
>> int main(int argc, char* argv[])
>> {
>> Base b;
>> Derived d;
>>
>> Base * pb1 = &b;
>> Base * pb2 = &d;
>>
>> pb1->Print_Size();
>> pb2->Print_Size();
>> return 0;
>> }[/color]
>
> Yeah, but since sizeof used the static type of the class, you have to
> re-write the method Print_Size -- with the exact same code -- in the
> derived class.[/color]

That's right. You could use templates to avoid that:

template<typename T>
struct Base
{
int b;
virtual void Print_Size() const
{
cout << sizeof(T) << endl;
}
};

struct Derived : Base<Derived>
{
//...
};
[color=blue]
> I was wondering if there was a way to access the information about the
> class size from its virtual table.[/color]

No. The C++ standard doesn't even define the term "virtual table" or
anything similar.

John Carson
Guest
 
Posts: n/a
#7: Mar 13 '06

re: Size of an inherited class ?


"Rolf Magnus" <ramagnus@t-online.de> wrote in message
news:dv4571$5f6$00$1@news.t-online.com[color=blue]
> François Fleuret wrote:
>[color=green]
>> Dear John,
>>
>> You wrote on 13 Mar 2006 12:51:47 MET:
>>[color=darkred]
>>> This seems to work
>>>
>>> #include <iostream>
>>> using namespace std;
>>>
>>> struct Base
>>> {
>>> int b;
>>> virtual void Print_Size()
>>> {
>>> cout << sizeof(*this) << endl;
>>> }
>>> };
>>>
>>>
>>> struct Derived : Base
>>> {
>>> int array[4];
>>> virtual void Print_Size()
>>> {
>>> cout << sizeof(*this) << endl;
>>> }
>>> };
>>>
>>> int main(int argc, char* argv[])
>>> {
>>> Base b;
>>> Derived d;
>>>
>>> Base * pb1 = &b;
>>> Base * pb2 = &d;
>>>
>>> pb1->Print_Size();
>>> pb2->Print_Size();
>>> return 0;
>>> }[/color]
>>
>> Yeah, but since sizeof used the static type of the class, you have to
>> re-write the method Print_Size -- with the exact same code -- in the
>> derived class.[/color]
>
> That's right. You could use templates to avoid that:
>
> template<typename T>
> struct Base
> {
> int b;
> virtual void Print_Size() const
> {
> cout << sizeof(T) << endl;
> }
> };
>
> struct Derived : Base<Derived>
> {
> //...
> };[/color]


This works nicely for Derived objects. But how do you declare a Base object?

--
John Carson



Rolf Magnus
Guest
 
Posts: n/a
#8: Mar 14 '06

re: Size of an inherited class ?


John Carson wrote:
[color=blue]
> "Rolf Magnus" <ramagnus@t-online.de> wrote in message
> news:dv4571$5f6$00$1@news.t-online.com[color=green]
>> François Fleuret wrote:
>>[color=darkred]
>>> Dear John,
>>>
>>> You wrote on 13 Mar 2006 12:51:47 MET:
>>>
>>>> This seems to work
>>>>
>>>> #include <iostream>
>>>> using namespace std;
>>>>
>>>> struct Base
>>>> {
>>>> int b;
>>>> virtual void Print_Size()
>>>> {
>>>> cout << sizeof(*this) << endl;
>>>> }
>>>> };
>>>>
>>>>
>>>> struct Derived : Base
>>>> {
>>>> int array[4];
>>>> virtual void Print_Size()
>>>> {
>>>> cout << sizeof(*this) << endl;
>>>> }
>>>> };
>>>>
>>>> int main(int argc, char* argv[])
>>>> {
>>>> Base b;
>>>> Derived d;
>>>>
>>>> Base * pb1 = &b;
>>>> Base * pb2 = &d;
>>>>
>>>> pb1->Print_Size();
>>>> pb2->Print_Size();
>>>> return 0;
>>>> }
>>>
>>> Yeah, but since sizeof used the static type of the class, you have to
>>> re-write the method Print_Size -- with the exact same code -- in the
>>> derived class.[/color]
>>
>> That's right. You could use templates to avoid that:
>>
>> template<typename T>
>> struct Base
>> {
>> int b;
>> virtual void Print_Size() const
>> {
>> cout << sizeof(T) << endl;
>> }
>> };
>>
>> struct Derived : Base<Derived>
>> {
>> //...
>> };[/color]
>
>
> This works nicely for Derived objects. But how do you declare a Base
> object?[/color]

Oh, I forgot. You need a third class that is the base to all Base<> template
instances. Here is a complete and tested example:

#include <iostream>

using std::cout;
using std::endl;

struct Base
{
virtual void Print_Size() const = 0;
virtual ~Base() {}
};

template<typename T>
struct TBase : Base
{
virtual void Print_Size() const
{
cout << sizeof(T) << endl;
}
};

struct Derived : TBase<Derived>
{
//...
int arr[32];
};

int main()
{
Base* test = new Derived;
test->Print_Size();
delete test;
}





John Carson
Guest
 
Posts: n/a
#9: Mar 14 '06

re: Size of an inherited class ?


"Rolf Magnus" <ramagnus@t-online.de> wrote in message
news:dv629v$n2k$03$1@news.t-online.com[color=blue]
> John Carson wrote:
>[color=green]
>> "Rolf Magnus" <ramagnus@t-online.de> wrote in message
>> news:dv4571$5f6$00$1@news.t-online.com[color=darkred]
>>>
>>> That's right. You could use templates to avoid that:
>>>
>>> template<typename T>
>>> struct Base
>>> {
>>> int b;
>>> virtual void Print_Size() const
>>> {
>>> cout << sizeof(T) << endl;
>>> }
>>> };
>>>
>>> struct Derived : Base<Derived>
>>> {
>>> //...
>>> };[/color]
>>
>>
>> This works nicely for Derived objects. But how do you declare a Base
>> object?[/color]
>
> Oh, I forgot. You need a third class that is the base to all Base<>
> template instances. Here is a complete and tested example:
>
> #include <iostream>
>
> using std::cout;
> using std::endl;
>
> struct Base
> {
> virtual void Print_Size() const = 0;
> virtual ~Base() {}
> };
>
> template<typename T>
> struct TBase : Base
> {
> virtual void Print_Size() const
> {
> cout << sizeof(T) << endl;
> }
> };
>
> struct Derived : TBase<Derived>
> {
> //...
> int arr[32];
> };
>
> int main()
> {
> Base* test = new Derived;
> test->Print_Size();
> delete test;
> }[/color]


You still haven't used a Base object. I am not sure in what way this version
improves on the earlier one.

Further, what happens with your scheme if you need a second level of
derivation: a Derived2 that derives from Derived?

--
John Carson


Closed Thread