2

カスタムメモリトラッキング(リーク防止、破損検出)を行うには、新しい配置を使用してC ++オブジェクトを作成する必要があります。これは正常に機能しますが、コンストラクターに引数を渡す方法を理解するのに苦労しています。マクロから呼び出されるため(ファイル+行を自動的に提供できるように)。

関数:

template <typename T>
T*
cpp_new(
    const char *file,
    size_t line
)
{
    T   *n = (T*)tracked_allocate(&memory_context, sizeof(T), file, line);

    if ( n )
    {
        construct(n);
    }
    else
    {
        throw std::bad_alloc();
    }

    return n;
}

これは、マクロを介して呼び出されます。

#define new_object(type)    cpp_new<type>(__FILE__, __LINE__)

新規配置:

template <typename T>
void
construct(
    T *obj
)
{
    obj = new (obj) T;
}

va_listマクロは、可変数の引数の拡張をカバーしますが、コンストラクターが持つ引数の数を指定したくない場合は、va_arg()を削除し、va_start()を使用できません。これは、フォーマットを想定しているためです。

これは私の頭を少し超えました:http ://www.drdobbs.com/cpp/calling-constructors-with-placement-new/232901023?pgno = 2

__VA_ARGS__new_objectから使用して、それらを構築関数に渡す方法はありますか?各オブジェクトにはコンストラクターが1つしかありませんが、さまざまなパラメーターを使用するさまざまなタイプのオブジェクトがあるため、手動によるメンテナンスを可能な限り削除したいと思います。

それとも、私が試みていることを一般的に行うためのより良い方法がありますか?

4

1 に答える 1

4

割り当てが成功した場合は、構成を処理しないでください。newそれが-expressionの仕事です。これは、トランザクションのような操作として正しく実行されます。すべてが成功するか、例外が伝播される前にクリーンアップが実行されます。

したがって、その責任から解放されて、マクロの仕事は、マクロだけが実行できること、つまりファイル名と行を取得することです。

これらのアイテムはアロケータ関数に渡すことができます/渡す必要があります。アロケータ関数は技術的には「新しい配置」ですが、ここではインプレースで構築されません。次のように、追加のユーザー定義引数があるという理由だけで新しい配置です。

bool hopefully( bool const c ) { return c; }

template< class X >
bool throw_( X const& x ) { throw x; }

void* operator new( size_t const size, char const* const filename, int const linenum )
{
    void* const p = tracked_allocate( &memory_context, size, filename, linenum );
    hopefully( p != 0 )
        || throw_( std::bad_alloc() )
    return p;
}

対応する配置の割り当て解除関数を定義する必要があります。そうしnewないと、コンストラクターが次をスローしたときに式の割り当て解除に失敗します。

void operator delete( void* const p )
{
    // Your custom deallocation.
}

void operator delete( void* const p, char const*, int )
{
    ::operator delete( p );
}

これで、マクロは次のように、関連する配置引数を提供する必要があります。

#define SOURCE_LINE_INFO __FILE__, __LINE__

次に、次のように言うことができます

new (SOURCE_LINE_INFO) MyType( arg1, arg2, arg3 )

より再利用可能なソリューションについてはstruct、ファイル名と行番号を保持するようにを定義することを検討してください。次に、マクロはそのタイプのインスタンスを構築することになり、より一般的に使用できます。特に、通話の記録に使用できます。

于 2012-10-01T04:13:14.083 に答える