私はC++を学んでおり、クラスでオブジェクトを使いたいと思っています。私のプログラムの出力は、私が予想していたので、データデストラクタが2回呼び出されることを私に混乱させます。私のオブジェクトは、 "データデータ(3);"コードブロックの最後でデストラクタを呼び出す必要があり、またrectsデストラクタが呼び出されると、rect内のデータのデストラクタも呼び出される必要があります。私が期待したように、コードブロックが終了してから2回、「データデストラクタ」を印刷します。しかし、それはまた、私のデータオブジェクトが作成された後、それを印刷します。なぜこれが起こり、データ内の割り当てられたメモリを正しく削除することができますか?デストラクタはどこにありますか?
class Data {
private:
int* data;
int size;
public:
Data() {
size = 10;
data = new int[size];
}
Data(int size)
: size(size) {
data = new int[size];
}
virtual ~Data() {
// delete data;
std::cout << "data destruktor" << std::endl;
}
void init(int val) {
for (int i = 0; i < size; i++)
data[i] = val;
}
int& operator[](int index) {
return data[index];
}
int getSize() const {
return size;
}
};
class Rect {
private:
Data data;
int width, height;
public:
Rect() {}
Rect(int width, int height, Data data, int val = 0)
: width(width), height(height), data(data) {
data.init(val);
}
int getWidth() const {
return width;
}
int getHeight() const {
return height;
}
int getArea() const {
return width * height;
}
Data& getData() {
return data;
}
};
int main() {
{
Data data(3);
std::cout << "data created" << std::endl;
Rect rect(5, 4, data, 9);
std::cout << "end of code block" << std::endl;
}
std::cout << "end of program" << std::endl;
system("pause");
return 0;
}
出力:
data created
data destruktor
end of code block
data destruktor
data destruktor
end of program
Re "しかし、データオブジェクトが作成された後にも出力されます。"では、値で 'Data'を渡しています。それは一時的なオブジェクトを作成します。それは破壊される。すべてがうまく動くので、 'init'メンバ関数を定義するように誘惑したアドバイス以外は心配する必要はありません。ちょうどそれをしないで、そのアドバイスのソースを「非常に疑わしい、その人の声明がデフォルトでは疑わしい」カテゴリに入れてください。ああ、申し訳ありませんが、私は見ませんでした:コピーコンストラクタがありません**。これにより、配列を2回「削除」できます。未定義の動作。代わりに 'std :: vector'を使用してください! –
@ Cheersandhth.-Alf関数のパラメータは一時オブジェクトではありません –
Rectオブジェクトを構築する際には、値によって 'data'変数を渡しています。これにより、そのオブジェクトのコピーが作成され、Rectコンストラクタからの復帰後に破棄されます。私はそれが混乱を引き起こしていると思います。 –