let baseclass know size of object

R

.rhavin grobert

guess you have a bouquet of paddingless structs (and your compiler
already cares for that) that all have one in common: their first
memeber has to be their size. As fas as i know (am i right?) a
baseclass get's in it's ctor the _baseclass-size_ when doing a sizeof
(this), so you cant fill that member in ctor automatically. Lets say
you want the derived-class way, e.g.:

typedef unsigned int UINT;
struct base {
base(UINT nSize) : m_nSize(nSize) {};
UINT size() const {return m_nSize;};
private:
UINT m_nSize;
};

struct d1, public base {
// .... //
};

now what would be the best way to automatically fill the m_nSize
memeber w/o calling a special init()-member for every derived class or
doing something like:

struct d. public base {
d() : base(sizeof(this)) {};
};


because depending on the deriviation, ctor d() may or may not have
some parameters and additional initalisations, so a macro would in the
end look even more complicated. is there a (perhaps templates) way to
say:

"if the struct is derived from 'base', one member of the ctors init-
list has to be a 'base(sizeof(this))' " ...?
 
B

Bart van Ingen Schenau

guess you have a bouquet of paddingless structs (and your compiler
already cares for that) that all have one in common: their first
memeber has to be their size. As fas as i know (am i right?) a
baseclass get's in it's ctor the _baseclass-size_ when doing a sizeof
(this), so you cant fill that member in ctor automatically. Lets say
you want the derived-class way, e.g.:
is there a (perhaps templates) way to
say:

"if the struct is derived from 'base', one member of the ctors init-
list has to be a 'base(sizeof(this))' " ...?

If the restriction that it only works for dynamically-allocated
structures is not a problem, you could define a class-specific
operator new() to collect this information.
Something like this:

<pseudocode>
class Base {
private:
static std::size_t lastSize;
public:
static void* operator new(std::size_t size)
{
lastSize = size;
return ::eek:perator new(size);
}
public:
Base() : mSize(lastSize)
{
lastSize = 0; /* reset to avoid undetectable bogus results */
}
private:
unsigned int mSize;
};
</pseudocode>

Bart v Ingen Schenau
 
R

.rhavin grobert

If the restriction that it only works for dynamically-allocated
structures is not a problem, you could define a class-specific
operator new() to collect this information.
Something like this:

<pseudocode>
class Base {
private:
  static std::size_t lastSize;
public:
  static void* operator new(std::size_t size)
  {
    lastSize = size;
    return ::eek:perator new(size);
  }
public:
  Base() : mSize(lastSize)
  {
    lastSize = 0; /* reset to avoid undetectable bogus results */
  }
private:
  unsigned int mSize;};

</pseudocode>

Bart v Ingen Schenau

nice idea, thx, i'll try!
 
P

peter koch

guess you have a bouquet of paddingless structs (and your compiler
already cares for that) that all have one in common: their first
memeber has to be their size. As fas as i know (am i right?) a
baseclass get's in it's ctor the _baseclass-size_ when doing a sizeof
(this), so you cant fill that member in ctor automatically. Lets say
you want the derived-class way, e.g.:

typedef unsigned int UINT;
struct base {
        base(UINT nSize) : m_nSize(nSize) {};
        UINT size() const {return m_nSize;};
private:
        UINT m_nSize;

};

struct d1, public base {
        // .... //

};

now what would be the best way to automatically fill the m_nSize
memeber w/o calling a special init()-member for every derived class or
doing something like:

struct d. public base {
        d() : base(sizeof(this)) {};

};

because depending on the deriviation, ctor d() may or may not have
some parameters and additional initalisations, so a macro would in the
end look even more complicated. is there a (perhaps templates) way to
say:

"if the struct is derived from 'base', one member of the ctors init-
list has to be a 'base(sizeof(this))' " ...?

You could also use the CRTP, although that would mean that you would
not derive directly from bar, but from an intermediate class:

template < typename T >
class BT: public B
{
BT(): B(sizeof(T)) {}
};

class D: public BT<D>
{
....
};

/Peter
 

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,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top