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.