0
  1. 「new」で生成されたオブジェクトは、この概念で正しく削除されるのだろうか。
  2. 「bind2nd」の代わりに「bind」を使用できません。どうすればいいですか?
  3. 最後の質問: 名前付き関数の代わりにラムダ項を使用して同じことを行うにはどうすればよいですか?

リストを使用する理由 オブジェクトがシーケンス化されていないため、ベクトルではなくリストを使用することにしました。最後に、「ウォーターフォールのような」コードをオブジェクト指向に導入したいと考えています。これは、基本的にパフォーマンスの問題のためです (ここで問題が表示されます)。そのため、コンテナーの階層内のオブジェクトにすばやくアクセスし、それらが互いに通信できるようにします。これも高速です。モジュラーシンセサイザーを思い浮かべてください。

class Layer {
    private:
    string name;
    bool active;
    public:
    Layer();
    Layer(string m_name, bool m_active);
    bool isName(string m_name);
};

// ... constructors

bool Layer::isName(string m_name) {
return name == m_name;
}

class Stack {
    public:
    list<Layer*> layer;
    list<Layer*>::iterator iter;
};

int main() {
Stack stack;
stack.layer.push_back(new Layer);
stack.layer.push_back(new Layer("snail", true));
stack.layer.push_back(new Layer("squirrel", false));

string search = "snail";
stack.layer.remove_if(bind2nd(mem_fun(&Layer::isName), search));

return 0;
}
4

1 に答える 1

7

いいえ、メモリを正しく管理していません。別の方法で行う必要がない限り、コードからほとんどの (すべてではないにしても) ポインターを消去します。

class Stack {
    public:
    list<Layer> layer;
    list<Layer>::iterator iter;
};

その後、メモリ管理はほぼ自動になります。

Stack stack;
stack.layer.push_back(Layer("snail", true));
stack.layer.push_back(Layer("squirrel", false));

十分に新しいコンパイラがある場合は、おそらく置き換えたいと思うでしょpush_backemplace_back

このような場合、ラムダはほぼ確実に以下よりも優れていstd::bindます。

stack.layer.remove_if([](Layer const &s) { return s.isName(search); }

余談ですがisName、文字列ではなく const 文字列への参照を取得するように変更することもできます (呼び出しごとに文字列をコピーする手間が省けます)。

あなたが示していることから、std::mapの代わりに使用することも検討しstd:listます。ルックアップ (1 つのこと) をより直接的にサポートします。

編集:私が言及する必要があるもう1つのポイントは、このような場合、本質的に常に「キー」としてほぼ確実に使用する1つのフィールド(この場合は名前)があり、オーバーロードしたい場合があるということoperator<ですoperator==。など、そのキー フィールドで作業するには:

class Layer { 
    // ...
    bool operator<(Layer const &other) { return name < other.name; }
    bool operator==(Layer const &other) { return name == other.name; }
};

これにより、ソート、削除などの操作がさらに簡単になります。上記のものは次のようになります。

 stack.layer.remove(search);
于 2012-06-08T21:57:16.480 に答える