3

私が使用するプログラム API のドキュメントには必要な情報が不足しているため、メソッドの使用方法を自分で理解しようとしましたHashMap::FindOrCreateEntry()

template <typename C> Entry* FindOrCreateEntry(const K& key, C& constructor, Bool& created)
{
    /* ... */
    Entry* e = (Entry*) _allocator.Alloc(SIZEOF(Entry), C4D_MISC_ALLOC_LOCATION);
    if (!e)
    {
        created = false;
        return nullptr;
    }
    e = constructor.ConstructHashMapEntry(e, key);
    /* ... */
    return e;
}

私が疑わしいのは、同じ名前の2番目の方法です。

struct DefaultEntryConstructor
{
    static Entry* ConstructHashMapEntry(void* ptr, const K& key)
    {
        return new (ptr) Entry(key);
    }
};

Entry* FindOrCreateEntry(const K& key, Bool& created)
{
    return FindOrCreateEntry(key, *(DefaultEntryConstructor*) nullptr, created); //lint !e413
}
  1. の呼び出しにテンプレート パラメータが渡されないのはなぜFindOrCreateEntry()ですか?
  2. この呼び出しはクラッシュするべきではありませんか? nullptr!を逆参照します。または、少なくとも、このようにすることは危険なはずですか? 私が間違っている場合は、私を修正してください。
4

1 に答える 1

3

1 FindOrCreateEntry() の呼び出しにテンプレート パラメータが渡されないのはなぜですか?

コンパイラは渡されたパラメータから型を推測できるためです。ここで、C = DefaultEntryConstructor.

2 この呼び出しはクラッシュしませんか? nullptr を逆参照します。または、少なくとも、このようにすることは危険なはずですか? 私が間違っている場合は、私を修正してください。

しかし静的なので、行DefaultEntryConstructor::ConstructHashMapEntry

e = constructor.ConstructHashMapEntry(e, key);

コンストラクターのは使用されません (nullptr であることは問題ではありません)。ポインターののみが関数呼び出しの解決に使用されます。


その静的メソッド呼び出しをもう少し詳しく見てみましょう。コンパイラがインスタンス化するとき

e = constructor.ConstructHashMapEntry(e, key);

Cの型を知っていconstructorます。したがって、最初のステップは、呼び出す関数を特定することです。この関数の型に応じて、呼び出しサイトは次の 4 つの型のいずれかになります。

  1. 通常の非仮想メソッド呼び出し: これにより、暗黙的thisなパラメーターを使用して通常のメソッド呼び出しが生成されるため、オブジェクト参照の値が使用されます。constructor
  2. 仮想メソッド: これは、何らかのメカニズム (通常は vtable) を使用して、実行時に関数ポインターをルックアップします: ルックアップと呼び出しの両方がオブジェクト参照またはポインターのに依存します
  3. 静的メソッド (私たちの場合): これは、暗黙的thisなパラメーターを持たない関数呼び出しを生成します。ここではオブジェクトののみが使用され、は完全に無視されます
  4. constexpr: オブジェクトのランタイム値は明らかにこれに影響を与えないため、使用されません

constructor.ConstructHashMapEntry(e, key)の代わりに静的な as を呼び出すのは紛らわしいかもしれませんがC::ConstructHashMapEntry(e, key)、この形式では、 の型に応じて、静的メソッド非静的メソッドのFindOrCreateEntry両方を使用できます。C

于 2013-06-25T13:33:50.103 に答える