RAII クラスが常にスタックに割り当てられるようにしたいと思います。
「new」演算子を介してクラスが割り当てられないようにするにはどうすればよいですか?
RAII クラスが常にスタックに割り当てられるようにしたいと思います。
「new」演算子を介してクラスが割り当てられないようにするにはどうすればよいですか?
クラスの 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;
};
私はあなたの動機を確信していません。
フリーストアでRAIIクラスを作成するのには十分な理由があります。
たとえば、RAIIロッククラスがあります。特定の条件が成立する場合にのみロックが必要なコードを通るパスがあります(これはビデオプレーヤーであり、ビデオをロードして再生している場合はレンダリングループ中にのみロックを保持する必要があります。何もロードされていない場合は、私はそれを必要としません)。したがって、フリーストアに(を使用してunique_ptr
)ロックを作成する機能は非常に便利です。ロックを解除する必要があるかどうかに関係なく、同じコードパスを使用できます。
つまり、次のようなものです。
unique_ptr<lock> l;
if(needs_lock)
{
l.reset(new lock(mtx));
}
render();
スタックにロックを作成することしかできなかったとしたら、それはできませんでした。
@ドクターピザ:
それはあなたが持っている興味深い点です。ただし、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();
私の特定の状況では、ロックが必要ない場合、ミューテックスさえ存在しないため、そのアプローチは適合するのがかなり難しいと思います。
私が本当に理解するのに苦労しているのは、フリー ストアでのこれらのオブジェクトの作成を禁止する正当な理由だと思います。