首页 > 解决方案 > 派生类中的 sizeof(*this) 和 decltype(*this)

问题描述

假设有类:

struct A {
  int a;

  virtual size_t GetMemoryUsage() const {
    return sizeof(*this);
  }
};

struct B : public A {
  int b;
};

而且可能还有更深层次的传承。

GetMemoryUsage()在这种情况下,我想要的是有一个方法可以返回对象在内存中占用的字节数。通常可以通过使用来实现sizeof(*this)。问题是(至少 AFAIU)我必须重写每个派生类中的方法并实际复制粘贴它的主体。我不喜欢重复的代码:)

我对么?如何通过仅从基类的方法调用子类来制作sizeof(*this)和返回我想要的子类?decltype(*this)有没有更优雅的解决方案?

标签: c++c++11inheritancesizeofdecltype

解决方案


您不必GetMemoryUsage手动为每个派生类实现,只需将其保留为纯虚拟即可。例如:

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

struct B : A
{
    int b;
};

但是,在创建对象时,必须实现该功能。您可以使用一个工厂函数来做到这一点,该函数使用纯虚拟的通用实现“装饰”类:

// 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)...));
}

用法:

void f(A& a) {
    auto object_size = a.GetMemoryUsage();
}

int main() {
    auto b = create<B>();
    f(*b);
}

您还可以使用此习惯用法以增量方式轻松实现接口层次结构。


推荐阅读