1

結果を返す必要があるときに、new で割り当てたスペースを削除するにはどうすればよいですか。これを使用したので、オブジェクトが見つからない場合は、ダミーのセンチネル値を持つオブジェクトを返します。

ClassObject* ClassObjectTwo::find(string findid) {
        ClassObject *sendback;
        bool found;

        for(vector<ClassObject>::iterator it = data.begin(); it != data.end(); it++) {
                if ( it->get_id() == findid) {
                        found = true;
                        sendback = &(*it);
                }
        }

        if(!found) {
                sendback = new ClassObject;
                sendback->set_key(100);
        }

        return sendback;
}

または、範囲外のときに破壊されるため、これは問題ではありません。私が考えることができる他の唯一の解決策は、オブジェクトをコンストラクターに配置し、コンストラクターを介して削除することです。1 つの関数に変数を追加したくなかっただけです。

4

4 に答える 4

5

関数の外で動的に作成されたオブジェクトを破棄してもまったく問題ありません。

ただし、この場合は NULL を返す方がよいでしょう。

于 2013-05-24T21:15:47.103 に答える
4

ここには学ぶ絶好の機会がありますので、質問から少し逸れても構いません。まず第一に、生のポインターを所有して作業しないという習慣を身につけるべきです。つまり、オブジェクトを割り当てて生のポインターに保持しないでください。生のポインターは、たとえば、sendbackタイプの関数内の変数ですClassObject *。「所有する」とは、自分でメモリを削除する責任があるということです。

代わりに、オブジェクトを動的に割り当てる必要がある場合は、オブジェクトの所有権を常にスマート ポインターに保持する必要があります。つまり、所有権の共有が本当に必要でない限りstd::unique_ptr、またはstd::shared_ptr優先して。unique_ptrC++11 と互換性のあるコンパイラがない場合は、Boost に相当するものboost::scoped_ptrboost::shared_ptr. そのため、オブジェクトを動的に割り当てたい場合は常にスマート ポインターに配置します。これにより、スマート ポインターがスコープ外になったときにオブジェクトが確実に破棄されます。動的に作成されたオブジェクトを返したい場合は、オブジェクトを保持するスマート ポインターを返します。経験則として、deleteコードを記述する必要がある場合は、おそらくスマート ポインターを使用する必要がありました。

たとえば、動的に作成された新しい ClassObject を作成するには、次のように記述します。

std::unique_ptr<ClassObject> myObj = std::unique_ptr<ClassObject>(new ClassObject());

またはさらに良いのは、 auto を使用して、型を明示的に記述する必要がないようにすることです。

auto myObj = std::unique_ptr<ClassObject>(new ClassObject());

c++14 では次のようになります。

auto myObj = std::make_unique<ClassObject>();

スマート ポインターを使用すると、例外が発生したときにこれらのオブジェクトが確実に削除されるようにすることで、潜在的な問題が発生するのを防ぐことができます。

ただし、あなたの場合、オブジェクトを返す必要はまったくありません。オブジェクトが見つからなかったことを示したい場合は、戻りNULLます (または、コンパイラで利用可能な場合は、実際には C++11 を使用する必要nullptrがあります)。別のオプションは、見つかったオブジェクトまたは見つからなかったオブジェクトにイテレータを返すdata.end()ことです。

関数のユーザーは、ポインターを返すオブジェクトが後続の操作によって破棄されないという保証がないため、関数を使用するときも非常に注意する必要がありますが、これはドキュメントの問題である可能性があります.

もう 1 つのポイントは、関数への引数をconst string &単なる a ではなくa として取得しstring、パラメーターの一時的なコピー (発生する可能性があります) を回避することです。

Herb Sutterのブログを見ると、ユースケースに非常によく似た質問についてさらに議論があります。

http://herbsutter.com/2013/05/13/gotw-2-solution-temporary-objects/

このテーマに関する詳細な議論は次の場所にあります。

http://herbsutter.com/2013/05/16/gotw-3-solution-using-the-standard-library-or-temporaries-revisited/

Herb Sutter は C++ に関する優れた本を多数執筆しており、C++ 言語のさらなる開発に積極的に参加しています。

乾杯!

于 2013-05-24T21:59:08.990 に答える
0

オブジェクトを返すとオブジェクトを作成する理由がわかりません。私の意見では意味がありません。呼び出し元は戻り値をチェックし、それが null の場合は、ダミー オブジェクトを作成するなどの処理を行う必要があります。メソッドが呼び出さfindれ、アイテムを検索して返すか、失敗を示す値を返すことが契約であることがわかります ( nullptr)。検索されたオブジェクトが見つからない場合に備えてオブジェクトを作成したい場合は、それを呼び出すfirst_or_defaultか、似たようなものを呼び出します。これが実際の動作であるためです。

于 2013-05-24T22:12:31.017 に答える
0

オブジェクトを関数外のポインターに代入すると、そこから削除してメモリ リークを回避できます。関数からオブジェクト ポインターが必要であることは理解しています。そのため、関数の外側を削除することが最も理にかなっているように思えます。使用後は削除します。null が返された場合は、何も削除する必要はありません。

于 2013-05-24T21:35:02.850 に答える