Topic: Determining an object's size


Author: David R Tribble <dtribble@technologist.com>
Date: 1999/04/01
Raw View
henk.devos@dzine.be wrote:
>> I need to know the "real" size of an object in a base class. The
>> actual object will always belong to a derived class. Is there any
>> good way to do this?

AllanW wrote:
> Here's one method that I think is portable. It works well for objects
> allocated via operator new, but objects on the stack or in arrays will
> have problems, as will derived classes that override operator new.
>
> In operator new, save the requested size somewhere. In the
> constructor, copy this size into a member variable; it can probably
> be const. Then define getSize() or something similar to do the runtime
> equivalent of sizeof().

A similar method is to add a size member to the base class (probably
making it protected), which is then set by every ctor including all
of the derived class ctors:

    class Base                         // Base class
    {
    protected:
        size_t  m_size;                // Actual object size
        ...

    public:
        size_t  getsize() { return m_size; }
        ...
    };

    Base::Base():
        m_size(sizeof(*this)), ...     // Sets m_size
    {
        ...
    }


    class Der: public Base             // Inherits Base
    {
        ...
    };

    Der::Der():
        m_size(sizeof(*this)), ...     // Sets m_size
    {
        ...
    }

This works regardless of how the objects are allocated (heap,
stack, or static).  It's also thread-safe.  The drawback is that
you have to remember to initialize the size member in every derived
ctor.  I'd don't see a way to enforce this.

Perhaps you could change the code so that Base::Base() initializes
m_size to 0, so that you could detect at runtime if you'd forgotten
to properly set m_size in a derived ctor (i.e., getsize() would
return 0).  The drawback here is that classes indirectly derived
from Base (i.e., classes derived from classes derived from Base)
could still have an improperly initialized m_size.

-- David R. Tribble, dtribble@technologist.com --
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: henk.devos@dzine.be
Date: 1999/03/25
Raw View
I need to know the "real" size of an object in a base class. The actual
object will always belong to a derived class. Is there any good way to do
this ? I can not use the sizeof operator, because i don't know the type of
the object at compile time. I could create a virtual function GetSize() and
require every class to override this function, but this solution isn't very
neat. This would mea&n documenting that you must override the function and
saying exactly how the function should look. Besides, there is no way to make
sure the function is always correctly overridden. Is there a way to use
type_info or something similar to determine the size ?

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/03/26
Raw View
henk.devos@dzine.be wrote:

> I need to know the "real" size of an object in a base class. The actual
> object will always belong to a derived class. Is there any good way to do
> this ? I can not use the sizeof operator, because i don't know the type of
> the object at compile time.

Correct

> I could create a virtual function GetSize() and
> require every class to override this function, but this solution isn't very
> neat.

That's exactly what I would do.

> This would mean documenting that you must override the function and
> saying exactly how the function should look.

Correct

> Besides, there is no way to make
> sure the function is always correctly overridden.

At least I don't know of any way to ensure that except code review.
All you can do is to make it pure in abstract classes.

> Is there a way to use
> type_info or something similar to determine the size ?

No, at least not portably (implementation can derive from
typeinfo and add runtime information (that's why the dtor
is virtual)).

--

Valentin Bonnard


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: William Roeder <roeder@titan.com>
Date: 1999/03/26
Raw View
henk.devos@dzine.be wrote:
>
> I need to know the "real" size of an object in a base class. The actual
> object will always belong to a derived class. Is there any good way to do
> this ? I can not use the sizeof operator, because i don't know the type of
> the object at compile time. I could create a virtual function GetSize() and
> require every class to override this function, but this solution isn't very
> neat. This would mea&n documenting that you must override the function and
> saying exactly how the function should look. Besides, there is no way to make
> sure the function is always correctly overridden. Is there a way to use
> type_info or something similar to determine the size ?
Not that I know of.

1) The virtual function was how I'd do it.
2) You could use dynamic_cast and then sizeof. Pro: It's always correct.
Con: New derived types must be added.
3) The real question is why do you need to know.  If it's to create a
duplicate, then the clone pattern will work.  Otherwise the visitor
pattern would.  The visitor itself would be a template.  See
http://rampages.onramp.net/~huston/dp/patterns.html
--
   __             _ __                    "Time is a great teacher,
  /  )     /  /  ' )  )          /        unfortunately, he kills all
 /--'  *  /  /    /--' _ _ /> _ /  _  __  his students." --- Berlioz
/__)__/\_/\_/\_  /  \_(_) (__(_/\_(/_/ (_        mailto:roeder@titan.com


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "AllanW {formerly AllanW@my-dejanews.com}" <allan_w@my-dejanews.com>
Date: 1999/03/27
Raw View
In article <7dbe9b$lgm$1@nnrp1.dejanews.com>,
  henk.devos@dzine.be wrote:
> I need to know the "real" size of an object in a base class. The actual
> object will always belong to a derived class. Is there any good way to do
> this ? I can not use the sizeof operator, because i don't know the type of
> the object at compile time. I could create a virtual function GetSize() and
> require every class to override this function, but this solution isn't very
> neat. This would mea&n documenting that you must override the function and
> saying exactly how the function should look. Besides, there is no way to make
> sure the function is always correctly overridden. Is there a way to use
> type_info or something similar to determine the size ?

Here's one method that I think is portable. It works well for objects
allocated via operator new, but objects on the stack or in arrays will
have problems, as will derived classes that override operator new.

In operator new, save the requested size somewhere. In the constructor,
copy this size into a member variable; it can probably be const. Then
define getSize() or something similar to do the runtime equivalent of
sizeof().

    #include <iostream>

    // The base class in question
    class myBase {
        const size_t size;
        static size_t xxsize;
    public:
        size_t getSize() { return size; }
        void *operator new(size_t size)
            { xxsize = size; return new char[size]; }
        myBase() : size(xxsize) {}
        virtual ~myBase() {}
        virtual void show() {
            std::cout << "myBase: getSize()=" << getSize()
                      << ", real size " << sizeof(*this) << std::endl;
        }
    };
    size_t myBase::xxsize = 0;

    // Derived classes don't need to do anything special,
    // but overriding operator new() is a no-no.
    class myDer1 : public myBase {
        int data[10]; // Ensure larger than myBase
    public:
        void show() {
            std::cout << "myDer1: getSize()=" << getSize()
                      << ", real size " << sizeof(*this) << std::endl;
        }
    };

    class myDer2 : public myBase {
        int data[20]; // Ensure larger than myBase
    public:
        void show() {
            std::cout << "myDer2: getSize()=" << getSize()
                      << ", real size " << sizeof(*this) << std::endl;
        }
    };

    int main() {
        myBase *x[3];
        x[0] = new myBase;
        x[1] = new myDer1;
        x[2] = new myDer2;
        for (int i=0; i<sizeof(x)/sizeof(x[0]); ++i)
        {
            x[i]->show();
            delete x[i];
        }
        return 0;
    }

----
Allan_W@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]