sizeof(*this) and decltype(*this) in derived classes

  • A+
Category:Languages

Suppose there are classes:

struct A {   int a;    virtual size_t GetMemoryUsage() const {     return sizeof(*this);   } };  struct B : public A {   int b; }; 

And there may be deeper inheritance.

What I want is to have a method which will return the number of bytes an object occupies in memory, GetMemoryUsage() in this case. Usually it can be achieved by using sizeof(*this). The problem is (at least AFAIU) that I have to override the method in each derived class and actually copy-paste its body. I don't like duplicated code :)

Am I correct? How can I make sizeof(*this) and decltype(*this) return what I want in subclasses, by calling them only from base class's methods? Is there a more elegant solution?


You do not have to implement GetMemoryUsage for each of your derived classes manually, just leave it as pure virtual. E.g.:

struct A {     virtual ~A() = default;     virtual size_t GetMemoryUsage() const noexcept = 0; };  struct B : A {     int b; }; 

When creating objects, however, that function must be implemented. You can do that using a factory function that "decorates" the class with a generic implementation of that pure virtual:

// Can alternatively be defined inside function template create. template<class T> struct GetMemoryUsageImpl : T {     using T::T;     size_t GetMemoryUsage() const noexcept final {         return sizeof(T);     } };  template<class T, class... Args> std::unique_ptr<T> create(Args&&... args) {     return std::unique_ptr<T>(new GetMemoryUsageImpl<T>(std::forward<Args>(args)...)); } 

Usage:

void f(A& a) {     auto object_size = a.GetMemoryUsage(); }  int main() {     auto b = create<B>();     f(*b); } 

You can also implement a hierarchy of interfaces incrementally easily using this idiom.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: