質問
次のクラスをコンパイルします
class Interface
{
virtual void doIt() = 0;
virtual ~Interface() = 0;
};
inline Interface::~Interface() {}
を使用して gcc -fdump-class-hierarchy
.
gcc
発する
Class Interface size=4 align=4 base size=4 base align=4 Interface (0x1a779c0) 0 nearly-empty vptr=((& Interface::_ZTV9Interface) + 8u)
「ほぼ空」にはどのような意味があるのでしょうか?それはどういう意味ですか?
解決
の C++ ABI 「ほぼ空の」クラスの定義と、それらが vtable の構築にどのように影響するかについての興味深い議論を提供します。
仮想ポインターを含むクラスですが、(おそらく) 仮想基底以外のデータは含まれません。特に、それは次のとおりです。
- 幅ゼロのビットフィールド以外の非静的データ メンバーはありません。
- 空、ほぼ空、または仮想ではない直接の基本クラスはありません。
- 非仮想のほぼ空の直接基本クラスが最大 1 つあり、
- 空であり、道徳的に仮想的ではなく、ゼロ以外のオフセットにある適切な基本クラスがありません。
ほぼ空の仮想ベースがオブジェクト サイズ、vtable サイズ、仮想呼び出しオーバーヘッドに与える影響を調査しているときに、これに遭遇しました。
他のヒント
私はそれがすべてではありませんメンバーとクラスをコンパイルした場合、あなたが得るものである、「空」と区別するためにだと仮定します。 「ほぼ空」HASA vtableのと何もそれを意味するようです。
C ++は、「空のベースの最適化」と呼ばれるものがあります。クラスには、メンバーがない場合は、それが基底クラスとして使われていたときにスペースを取る必要はありません。これが重要である理由の例はstd::unary_function<T, U>
です。これは、型定義の簡単なセットを提供するために存在しています。これらのtypedefがあなた数子クラスの大きさに貢献してはいけません。
、このポインタは、おそらく派生クラスと共有することができます。あなたは、単にベースクラスの後、独自のメソッドを追加して派生クラスのvtableのを作成します。
これで、同様の「余分なオーバーヘッド」基底クラスを達成することができます。どうやらGCCは "ほぼ空" ことを呼び出します。
それだけのvtable、ノーデータフィールドを持っています。