在派生类中sizeof(*this)和decltype(*this)

Ale*_*xey 3 c++ inheritance sizeof decltype c++11

假设有类:

struct A {
  int a;

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

struct B : public A {
  int b;
};
Run Code Online (Sandbox Code Playgroud)

并且可能存在更深层次的继承.

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

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

Max*_*kin 10

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

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

struct B : A
{
    int b;
};
Run Code Online (Sandbox Code Playgroud)

但是,在创建对象时,必须实现该功能.您可以使用工厂函数来执行此操作,该函数使用该纯虚拟的通用实现"修饰"该类:

// 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)...));
}
Run Code Online (Sandbox Code Playgroud)

用法:

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

int main() {
    auto b = create<B>();
    f(*b);
}
Run Code Online (Sandbox Code Playgroud)

您还可以使用此习惯用法以增量方式逐步实现接口层次结构.