3

別のクラス Form のオブジェクトへのメンバー属性ポインターを持つクラス Agent があります。

Agent.h

...//snip includes
class Agent{
private:
  Form* mvForm_ptr;
  ...
public:
  Agent();
  ~Agent();
  ...//snip additional functionality, but no copy-constructor
};

エージェント.cpp

#include "Agent.h"
Agent::Agent(){
  mvForm_ptr = new Form();
}
Agent::~Agent(){
  delete mvForm_ptr;
}
...

ご覧のとおり、Agent の明示的なコピー コンストラクターはありません。その後、次のように Agent を使用します。

Agent player;
std::vector<Agent> agentsVector;
agentsVector.push_back(player);

これは、~Agent が EXC_BAD_ACCESS 例外をスローしているとエラー レポートが主張する SIGSEGV クラッシュの原因のようです。ここでvector::push_back を読むと、push_back が渡された値をコピーしようとしているようです。クラス Agent にコピー コンストラクターがないため、暗黙のコピー試行時にフォーム ポインターはどうなりますか? コンパイラによって生成された暗黙的なコピー コンストラクターでポイント先の値が失われた場合、明示的なコピー コンストラクターを追加すると、不正なアクセス例外が解決されますか? 上記のクラス Agent のコピー コンストラクターはどのように実装する必要がありますか? これは 3 のルールで説明されている前提の例ですか?

4

2 に答える 2

2

暗黙のコピー試行時に Form ポインタはどうなりますか?

何が起こるかというと、ポインター データ メンバーがコピーされるということです。つまり、元のオブジェクトとコピーされたオブジェクトの両方が同じオブジェクトを指しているということです。これは、寿命が尽きたときに両方が削除を試みることを意味します。これらの削除のうち、成功できるのは 1 つだけです。もう 1 つは未定義の動作につながります。

C++11 ではstd::unique_ptr<Form>、生のポインターの代わりに を保持することで、この問題を修正できます。C++03 では、3 の規則に従います。

于 2013-03-11T21:44:52.427 に答える
1

コピー演算子または代入演算子を指定しなかったため、コンパイラが生成し、ポインターはコピーされますが、フォームはコピーされません。エージェントが破壊されるたびに、ポインタが解放され、同じメモリが複数回解放されます。

簡単な修正は、shared_ptr を使用して、エージェントがなくなったときにのみフォームが削除されるようにすることです。

于 2013-03-11T21:46:03.647 に答える