提问人:Tao 提问时间:10/9/2023 最后编辑:Vlad from MoscowTao 更新时间:10/9/2023 访问量:133
在 C++ 中创建和删除对象
Object creation and delete in C++
问:
我有下面非常简单的代码来理解C++对象的创建和删除。输出并不是我所期望的。为什么?
class Box{
public:
static int count;
Box(double x, double y, double z) : length(x),width(y),height(z){
cout << "Box object created with " << length << " " << width << " " << height << endl;
count++;
cout << "Count after creation: " << count << endl;
}
~Box(){
cout << "Object deleted!" << endl;
count--;
cout << "Count after delete: " << count << endl;
}
Box operator + (Box *b){
return Box(length + b -> length, width + b -> width, height + b -> height);
}
Box operator + (Box b){
return Box(length + b.length, width + b.width, height + b.height);
}
private:
double length;
double width;
double height;
};
int Box::count = 0;
int main()
{
Box b1 = Box(1,1,1);
Box b2 = Box(2,2,2);
Box b3 = b1 + b2;
cout << "Here I am expecting 3, but get 2: " << Box::count << endl;
return 0;
}
我运行代码并得到以下输出:
Box object created with 1 1 1
Count after creation: 1
Box object created with 2 2 2
Count after creation: 2
Box object created with 3 3 3
Count after creation: 3
Object deleted!
Count after delete: 2
Here I am expecting 3, but get 2: 2. // I am expecting 3 there, b1, b2 and b3
Object deleted!
Count after delete: 1
Object deleted!
Count after delete: 0
Object deleted!
Count after delete: -1 // how can this been negative!
答:
3赞
Vlad from Moscow
10/9/2023
#1
程序的意外行为与以下声明有关:operator +
Box operator + (Box b){
return Box(length + b.length, width + b.width, height + b.height);
}
由于该参数不接受引用的参数,因此在此声明中
Box b3 = b1 + b2;
这相当于
Box b3 = b1.operator +( b2 );
使用默认的复制构造函数为 Operator 函数的参数创建了一个新对象。此对象的值与对象相同。Box b
count
2
b2
然后由于此声明中的复制/移动省略
Box b3 = b1 + b2;
使用构造函数创建对象b3
Box(double x, double y, double z) : length(x),width(y),height(z){
cout << "Box object created with " << length << " " << width << " " << height << endl;
count++;
cout << "Count after creation: " << count << endl;
}
因此,此对象的值等于 。count
3
另一方面,使用析构函数删除在 中创建的参数。结果,的值递减,现在等于尽管存在活的对象。operator +
count
2
3
而这些消息
Count after creation: 3
Object deleted! // <===
Count after delete: 2 // <===
关于删除运算符 functon 的局部对象(参数)的报告。
因此,当最后一个对象被销毁时,的值将等于 。count
-1
您可以通过以下方式声明operator +
Box operator + (const Box &b){
return Box(length + b.length, width + b.width, height + b.height);
}
以获得预期的结果。在这种情况下,将不会创建使用默认复制构造函数的类型的冗余对象,因为该对象将通过引用传递给 ,并且不会创建该类型的中间对象。Box
b2
operator +
Box
否则,您需要为创建的新对象定义显式递增的复制构造函数。count
评论
Box b3 = b1 + b2;
b3
Box(Box const&)
++count;
this