I am trying to get the size of a derived class, but I can't...
class one_t {
size_t getsizeof() { return sizeof(*this); }
... other members ...
};
class two_t : public one_t {
... supplemental members ...
};
void main()
{
two_t _2;
::cout << _2.getsizeof();
}
The output is always 8!
CodePudding user response:
C doesn't work the way you are attempting.
Even though you are calling getsizeof()
on a two_t
object, the implicit this
pointer that is inside of one_t::getsizeof()
is a one_t*
pointer, which you are dereferencing, so you end up passing a one_t&
reference to sizeof()
. It doesn't know this
is really pointing at a two_t
object, it can only return the size of whatever you actually give it, which in this case is the size of one_t
.
To accomplish what you want, you can make getsizeof()
be virtual
in one_t
and override
it in two_t
, eg:
class one_t {
public:
virtual size_t getsizeof() const { return sizeof(*this); }
... other members ...
};
class two_t : public one_t {
public:
size_t getsizeof() const override { return sizeof(*this); }
... supplemental members ...
};
void main()
{
one_t _1;
std::cout << _1.getsizeof(); // returns sizeof(one_t)
two_t _2;
std::cout << _2.getsizeof(); // returns sizeof(two_t)
}
Alternatively, you can use Curiously Recurring Template Pattern (provided you never make instances of one_t
directly), eg:
template<typename Derived>
class one_t {
public:
size_t getsizeof() const { return sizeof(Derived); }
... other members ...
};
class two_t : public one_t<two_t> {
public:
... supplemental members ...
};
void main()
{
// one_t<> _2; // illegal
// std::cout << _2.getsizeof();
two_t _2;
std::cout << _2.getsizeof(); // returns sizeof(two_t)
}
Alternatively, in C 23 and later, you can use Deducing this instead of CRTP, eg:
class one_t {
public:
template<class Self>
size_t getsizeof(this const Self& self) const { return sizeof(self); }
... other members ...
};
class two_t : public one_t {
public:
... supplemental members ...
};
void main()
{
one_t _1;
std::cout << _1.getsizeof(); // Self is deduced as one_t
two_t _2;
std::cout << _2.getsizeof(); // Self is deduced as two_t
}
CodePudding user response:
For starters according to the C Standard the function main shall have the return type int
int main()
You need to declare the function as virtual. For example
#include <iostream>
int main()
{
class one_t
{
public:
virtual ~one_t() = default;
virtual size_t getsizeof() const { return sizeof( *this ); }
int x;
};
class two_t : public one_t
{
public:
size_t getsizeof() const override { return sizeof( *this ); }
int y;
};
std::cout << one_t().getsizeof() << '\n';
std::cout << two_t().getsizeof() << '\n';
}
The program output might look like
8
12