私はかなり大規模な C++ プロジェクトに取り組んでいますが、残念ながら C++ を最大限に活用できていません。コードの大部分は、ばかげた C++ クラスでラップされた単純な C のままです。
そこで、C++ と STL をいくつか導入して、コードをより読みやすく、より安全なものにしようとしました。
ただし、ベクトルをオブジェクト メンバーに割り当てると、奇妙なクラッシュ (正確にはデバッグ エラー) が発生します。これを想像してください:
class A
{
public:
// Default constructor
A()
{
initialize(std::vector<unsigned long>());
};
A(const std::vector<unsigned long> &data)
{
initialize(data)
};
~A() {};
void initialize(const std::vector<unsigned long> &data)
{
m_data = data;
};
private:
std::vector<unsigned long> m_data;
};
次に、コードの別の場所で、次のように呼び出します。
a.initialize(std::vector<unsigned long>());
ただし、プログラムはデバッグ エラーで終了します: vector iterators incompatible. この割り当てで発生します。
m_data = data;
...コピーを作成する必要があります。これが私がやろうとしていることです。
ただし、この行を次のように変更すると:
m_data = std::vector<unsigned long>(data);
...すべてが期待どおりに機能します。
私の質問は次のとおりです。なぜですか?そして、これは空のベクトルでオブジェクトを初期化する正しい方法ですか?
実際のクラスははるかに大きく、渡されるメンバーがはるかに多いことに注意してください。これが、初期化関数を使用する理由です。また、既存の配列を渡す可能性もあるため、空または既存のデータで初期化できる必要があります。
編集: クラッシュの原因が見つかりました。私が見ているコードは、実際には少し異なる動作をすることがわかりました:
A *pA = malloc(...); // Not really malloc but a wrapper for a WINAPI-Alloc
// Some stuff happens in between
pA->initialize(std::vector<unsigned long>());
したがって、実際には A のコンストラクターが呼び出されたことがないため、ベクター メンバー (m_data) のコンストラクターも実行されませんでした。そのため、宛先ベクトルがまだ構築されていないため、コピー関数を暗黙的に呼び出すときにコンストラクターの割り当てが機能し、クラッシュしました。さて、教訓を学び、改善するためのより恐ろしいコード:)
ありがとう!