0

クラスタイプのnew演算子をオーバーロードして、ヒープではなくスタックにメモリを割り当てるにはどうすればよいですか(基本的に、ユーザーが後でdeleteを呼び出す必要がないようにするため)。

このようなものはどうですか?

class A{
    private:
        A(int i):
           this->i(i);
        {}
        A a;
        int i;

    public:
        void* operator new(size_t sz){
            a(12);
        }
};

上記の解決策は機能しますか?

4

4 に答える 4

9

しないでください!

自動ストレージを使用する...

newオペレーターは動的割り当て(「ヒープ上」と呼んでいるもの)を実装するように設計されており、独自のアロケーターを提供することはできますが、自動保存期間のオブジェクトのスコープ規則(あなたが何であるか)に従うようにねじることはできません。「スタック上」を呼び出す)。

代わりに、次のように記述します。

MyType myobject;  // automatic storage duration

...またはスマートポインタ...

または、動的な保存期間を気にせず、後で手動で破棄することだけを避けたい場合は、スマートポインターを使用します。

std::unique_ptr<MyType> myptr(new myobject());  // unique, dynamic storage duration
std::shared_ptr<MyType> myptr(new myobject());  // shared, dynamic storage duration

これらは両方ともC++11(std::)とBoost(boost::)にあります。

...または配置new

別のアプローチは新しい配置かもしれませんが、これは暗くて危険な移動経路であり、この段階では絶対にお勧めしません。または、率直に言って、どの段階でも...そして通常は手動で破壊する必要があります。あなたが得るのはキーワードを使うことだけですnew、それは無意味に思えます。

于 2012-10-29T14:33:53.783 に答える
2

ここでの良い答えは次のとおりだと思います。

演算子 new をオーバーロードしないでください。

それでもその道を進みたい場合は、この質問を見ることができます。

そうでない場合は、いつでもスマート ポインターまたは共有ポインターを使用して、ユーザーが割り当てられたメモリを削除する必要がないようにすることができます。

于 2012-10-29T14:35:39.020 に答える
1

何を聞かれているのか分からないようです。定義上、 new 演算子はヒープにメモリを割り当てます。スタック上にオブジェクトを作成するには、それをローカル変数として宣言するだけです。

実際にやりたいことを見て、これが素晴らしいと思った理由は次のとおりだとおっしゃいました。

基本的に、ユーザーが後で削除を呼び出す必要がないように

そして、その機能はスマート ポインターを使用して実装されます。代わりに、これらの学習に時間を費やすことを強くお勧めします。

于 2012-10-29T14:34:48.973 に答える
1

自動変数だけではないのはなぜですか(「スタック上」にあり、デストラクタを手動で呼び出す必要はありません:

int foo() {
  A a;
  int i;
  ...
  // don't need to call delete

}


あなたの質問に文字通り答えるために、ユーザーからメモリを取得する新しい配置があります - したがって、このメモリを自動バッファとして持つことができます:

  alignas(int) char buffer[sizeof(int)];
  int* p = new (buffer) int;
  //           ^^^^^^^^

非 POD オブジェクトの場合 - delete を呼び出す必要はありませんが、手動でデストラクタを呼び出す必要があります。

  class A { public: ~A(){} };
  alignas(A) char buffer[sizeof(At)];
  A* p = new (buffer) A;
  //         ^^^^^^^^
  p->~A();

alignasは C++11 の新機能です。C++03 では、適切なアラインメントを別の方法で処理する必要があります。適切にアラインされたメモリが返される必要がありますnew。そうでない場合、動作は未定義です。

于 2012-10-29T14:35:16.983 に答える