次のように定義されたクラスがあります (Accelerated C++ を読んだことがある人は、このクラスになじみがあるかもしれません)。
class Student_info{
public:
Student_info() : midterm(0.0), final(0.0) {};
Student_info(std::istream& is){read(is);};
Student_info(const Student_info& s);
~Student_info();
Student_info& operator=(const Student_info& s);
//Getters, setters, and other member functions ommited for brevity
static int assignCount;
static int copyCount;
static int destroyCount;
private:
std::string name;
double midterm;
double final;
double finalGrade;
std::vector<double> homework;
};
typedef std::vector<Student_info> stuContainer;
bool compare(const Student_info& x, const Student_info& y);
関数calculator()は、このタイプのオブジェクトを利用します。関数の一部として、(既に宣言されている) Student_info オブジェクトのベクトルは、ライブラリの汎用ソート関数を使用してソートされます。私のプログラムはこの時点を過ぎても進行しません (ただし、NetBeans によると、例外はスローされず、プログラムは正しく終了します)。
sort 関数は、コンテナーに保持されている型の代入演算子を多用しますが、定義したものの何が問題なのかを見つけることができないようです (定義する前に、プログラムは適切に機能していました)。Accelerated C++ によると (または、少なくともこれが私が解釈した方法です)、代入演算子が機能するはずの適切な方法は、最初に左のオペランドを破棄し、次に右のオペランドと等しい値で再度構築することです。したがって、これは私のオーバーロードされた operator= 定義です。
Student_info& Student_info::operator=(const Student_info& s)
{
if(this != &s)
{
this->~Student_info();
destroyCount++;
*this = s;
}
return *this;
}
ご覧のとおり、以下で定義されている Student_info コピー コンストラクターを呼び出します。
Student_info::Student_info(const Student_info& s)
{
name = s.name;
midterm = s.midterm;
final = s.final;
finalGrade = s.finalGrade;
homework = s.homework;
copyCount++;
}
sort ステートメントを省略すると、プログラムが正しく機能し、copyCount (コピー コンストラクターと operator= でのみ変更される) が 0 より大きいため、コピー コンストラクターは正しく機能します。
では、代入演算子の何が問題なのですか? 呼び出し元の Student_info オブジェクトの破棄と関係がありますが、破棄しない以外に修正する方法がわかりません。
(ちなみに、コピー コンストラクタ、デストラクタ、および代入演算子の作成は、Accelerated C++ の演習で必要になります...これらの関数の合成バージョンが私のクラスには明らかに十分であることを認識しています)