3

演算子new[]を使用して割り当てられた単一要素のサイズまたは要素数を取得する方法はありますか?

私が意味したのは:

void* Object::operator new[](size_t size)
{
    void *temp = ::operator new(size);

    //Get size of single element or count of elements being allocated

    return temp;
}

なぜそれが必要なのか:

operator new(size_t)オブジェクトがヒープに割り当てられている場合にoperator new[](size_t)のみ呼び出されるため、これに基づいてc++ガベージコレクションを作成することを考えました。

  1. Objectすべてのオブジェクトはクラスから継承します
  2. Objectクラスはオーバーライドoperator new(size_t)し、operator new[](size_t)次のようになります。

    void* Object::operator new(size_t size)
    {
        Object& result = *static_cast<Object*>(::operator new(size));
        result.referenceCount = (int)&result;
        return &result;
    }
    
  3. コンストラクターObjectはこの情報を使用します:

    Object::Object()
    {
        if ((void*)referenceCount != this)
        {
            referenceCount = -1; //stack object no reference counting
        }
        else
        {
            referenceCount = 1; //heap object count references
        }
    }
    
  4. 使用するガベージコレクタのユーザーreferenceCountフィールド。

私が今必要としているのは、operator new[](size_t)設定するために実装するreferenceCountことです。そのため、単一要素のサイズまたは要素数が必要です。operator new[](size_t)問題外のすべてのオブジェクトに強い。

何か案は?

4

1 に答える 1

3

これは私には非常にJava風のようです。プログラムをJavaで書く方が簡単でしょうか?慣用的なC++を最初に使用すれば、将来C++コードを保守する必要がある人は誰でもそれを高く評価するでしょう。たとえば、から継承するすべてのものに基づいてガベージコレクションを実装しようとするのではなく、スマートポインタを使用してメモリを管理しますObject

条件のリストから「多重継承は禁止されています」を省略したことを指摘しておく必要があります。多重継承が存在する場合、初期化されていない生のメモリのキャストはObject*、の正しいアドレスにアクセスするために必要なポインタ調整を行わない可能性があるためです。referenceCount

さらに、のメモリがreferenceCountたまたま構築時にスタックベースのアドレスを保持している場合Object、コードはそれがヒープに割り当てられていると信じ、スタックポインタを削除すると最終的にUBになります。

しかし、それでも本当に本当にこれを実行したい場合は、CRTPを使用して配列の新しい演算子を各子クラスに自動的に挿入するのが唯一の選択肢だと思います。少なくともそうすれば、すべての子供のために自分で書く必要はありません。

于 2012-12-28T21:30:09.163 に答える