49

RAII クラスが常にスタックに割り当てられるようにしたいと思います。

「new」演算子を介してクラスが割り当てられないようにするにはどうすればよいですか?

4

4 に答える 4

59

クラスの new 演算子を private に宣言するだけです。

class X
{
    private: 
      // Prevent heap allocation
      void * operator new   (size_t);
      void * operator new[] (size_t);
      void   operator delete   (void *);
      void   operator delete[] (void*);

    // ...
    // The rest of the implementation for X
    // ...
};  

'operator new' を非公開にすることで、クラス外のコードが 'new' を使用して X のインスタンスを作成することを効果的に防ぎます。

物事を完了するには、「operator delete」と両方の演算子の配列バージョンを非表示にする必要があります。

C++11 以降、関数を明示的に削除することもできます。

class X
{
// public, protected, private ... does not matter
    static void *operator new     (size_t) = delete;
    static void *operator new[]   (size_t) = delete;
    static void  operator delete  (void*)  = delete;
    static void  operator delete[](void*)  = delete;
};

関連する質問: オブジェクトのスタック割り当てを防止し、'new' でのみ開始できるようにすることは可能ですか?

于 2008-09-24T01:18:59.350 に答える
7

私はあなたの動機を確信していません。

フリーストアでRAIIクラスを作成するのには十分な理由があります。

たとえば、RAIIロッククラスがあります。特定の条件が成立する場合にのみロックが必要なコードを通るパスがあります(これはビデオプレーヤーであり、ビデオをロードして再生している場合はレンダリングループ中にのみロックを保持する必要があります。何もロードされていない場合は、私はそれを必要としません)。したがって、フリーストアに(を使用してunique_ptr)ロックを作成する機能は非常に便利です。ロックを解除する必要があるかどうかに関係なく、同じコードパスを使用できます。

つまり、次のようなものです。

unique_ptr<lock> l;
if(needs_lock)
{
    l.reset(new lock(mtx));
}
render();

スタックにロックを作成することしかできなかったとしたら、それはできませんでした。

于 2008-09-24T02:27:10.340 に答える
2

@ドクターピザ:

それはあなたが持っている興味深い点です。ただし、RAII イディオムが必ずしもオプションではない場合があることに注意してください。

とにかく、おそらくジレンマに対処するためのより良い方法は、ロックが必要かどうかを示すパラメーターをロック コンストラクターに追加することです。例えば:

class optional_lock
{
    mutex& m;
    bool dolock;

public:
    optional_lock(mutex& m_, bool dolock_)
        : m(m_)
        , dolock(dolock_)
    {
        if (dolock) m.lock();
    }
    ~optional_lock()
    {
        if (dolock) m.unlock();
    }
};

次に、次のように記述できます。

optional_lock l(mtx, needs_lock);
render(); 
于 2008-09-24T05:45:04.810 に答える
0

私の特定の状況では、ロックが必要ない場合、ミューテックスさえ存在しないため、そのアプローチは適合するのがかなり難しいと思います。

私が本当に理解するのに苦労しているのは、フリー ストアでのこれらのオブジェクトの作成を禁止する正当な理由だと思います。

于 2008-09-24T11:28:53.003 に答える