有没有办法通过删除“vptr”来减小对象的大小

-1 c++ virtual crtp vtable vptr

我有一个使用 CRTP 和 C++20 的代码:

template<class Derived>
class Base {
public:

    void m() {
        static_cast<Derived*>(this)->feature();      
    }
   
    virtual constexpr void feature() = 0;
}

class BaseImpl: public Base<BaseImpl> {
     virtual constexpr void feature() final override  { // ... };
}
Run Code Online (Sandbox Code Playgroud)

有没有办法删除vptr,这样对象就不会占用 8 个字节(对于 x64),而只占用 1 个字节?(因为它从不使用运行时多态性)?

在实际代码中,层次结构要复杂得多,有 2 个vptr(因此需要 16 个字节)。是否有类似 GCC 或 MSVC 的扩展?

是的,当然,解决方案之一就是删除该virtual方法。但由于它具有复杂的层次结构,它带来了极其丑陋的错误和不可维护的代码,因为程序员应该通过读取不可读的模板实例化错误来猜测必须实现哪些方法。

整个目标是实现类似 Java 的层次结构(具有接口、覆盖检查等),但具有零成本抽象。

我做了一些实验(探索代码反汇编),编译器完全优化了所有虚拟调用,提供了零成本抽象。除了它将对象扩展为具有vptr我的代码中从未使用过的 a 。

我发现了类似的东西__declspec(novtable),但vptr仍然占用空间。是的,物体的尺寸尽可能小是极其重要的。

Moo*_*uck 8

您正在使用 CRTP,它使用静态调度。绝对没有理由在这里使用虚拟。如果您想确保该方法存在且具有正确的签名,请使用static_assert.

template<class Derived>
class Base {
public:

    void m() {
        static_cast<Derived*>(this)->feature();      
    }
    
    ~Base() {
        static_assert(std::is_same_v<void,decltype(static_cast<Derived*>(this)->feature())>);
    }
};

class BaseImpl: public Base<BaseImpl> {
public:
     constexpr void feature()  {  };
};
Run Code Online (Sandbox Code Playgroud)