这是代码
#include <iostream>
#include <stdio.h>
using namespace std;
class Point {
private:
int x;
int y;
public:
Point(int x, int y) : x(x), y(y) {}
~Point() {
printf("Point destroyed: (%d, %d)\n", x, y);
}
};
class Square {
private:
Point upperleft;
Point lowerright;
public:
Square(int x1, int y1, int x2, int y2) : upperleft(x1, y1), lowerright(x2, y2) {}
Square(Point p1, Point p2) : upperleft(p1), lowerright(p2) {}
~Square() {
printf("Square destroyed.\n");
}
};
int main(int argc, char const* argv[])
{
Point p1(1, 2);
Point p2(3, 4);
Square s1(p1, p2);
return 0;
}
编译(g++ x.cpp
)并运行后,我得到了以下结果:
Point destroyed: (1, 2)
Point destroyed: (3, 4)
Square destroyed.
Point destroyed: (3, 4)
Point destroyed: (1, 2)
Point destroyed: (3, 4)
Point destroyed: (1, 2)
我希望每个Point都被销毁两次,但它们会被销毁三次。为什么呢?
答案 0 :(得分:4)
由于
Square(Point p1, Point p2)
接受按值传递的参数,该参数创建传递给它的参数的副本。你有
Square
构造函数Square
实例的成员变量3个实例。
答案 1 :(得分:2)
将它们复制到构造函数
中尝试Square(const Point& p1,const Point& p2) : upperleft(p1), lowerright(p2) {}
结果
Square destroyed.
Point destroyed: (3, 4)
Point destroyed: (1, 2)
Point destroyed: (3, 4)
Point destroyed: (1, 2)
答案 2 :(得分:2)
此构造函数
Square(Point p1, Point p2) : upperleft(p1), lowerright(p2) {}
按值接受Point类型的对象。因此,这些作为构造函数参数创建的临时对象也将被删除。
您可以按以下方式定义构造函数
Square( const Point &p1, const Point &p2) : upperleft(p1), lowerright(p2) {}
在调用期间转义创建临时对象。
看到调用析构函数的顺序很有趣
Point destroyed: (1, 2)
Point destroyed: (3, 4)
Square destroyed.
Point destroyed: (3, 4)
Point destroyed: (1, 2)
Point destroyed: (3, 4)
Point destroyed: (1, 2)
这两行
Point destroyed: (1, 2)
Point destroyed: (3, 4)
表示编译器首先创建第二个参数Point(3,4),然后创建第一个参数Point(1,2)。它们将以相反的顺序删除。
这两行
Point destroyed: (3, 4)
Point destroyed: (1, 2)
表示首先创建数据成员左上角,因为它在lowerright之前声明,然后创建了lowerright。同样,它们会以相反的顺序删除。
最后这两行
Point destroyed: (3, 4)
Point destroyed: (1, 2)
表示首先创建Point(1,2),因为它是在main(而Point)中的Point(3,4)之前定义的,然后创建了Point(3,4)。它们以相反的顺序删除。
答案 3 :(得分:0)
使用引用:
销毁两次#include <iostream>
#include <stdio.h>
using namespace std;
class Point {
private:
int x;
int y;
public:
Point(int x, int y) : x(x), y(y) {}
~Point() {
printf("Point destroyed: (%d, %d)\n", x, y);
}
};
class Square {
private:
Point upperleft;
Point lowerright;
public:
Square(int x1, int y1, int x2, int y2) : upperleft(x1, y1), lowerright(x2, y2) {}
Square(Point& p1, Point& p2) : upperleft(p1), lowerright(p2) {}
~Square() {
printf("Square destroyed.\n");
}
};
int main(int argc, char const* argv[])
{
Point p1(1, 2);
Point p2(3, 4);
Square s1(p1, p2);
return 0;
}
使用指针消灭一次:
#include <iostream>
#include <stdio.h>
using namespace std;
class Point {
private:
int x;
int y;
public:
Point(int x, int y) : x(x), y(y) {}
~Point() {
printf("Point destroyed: (%d, %d)\n", x, y);
}
};
class Square {
private:
Point* upperleft;
Point* lowerright;
public:
Square(int x1, int y1, int x2, int y2) {
Point* ul = new Point(x1, y1);
Point* lr = new Point(x2, y2);
upperleft = ul;
lowerright = lr;
}
Square(Point* p1, Point* p2) : upperleft(p1), lowerright(p2) {}
~Square() {
printf("Square destroyed.\n");
}
};
int main(int argc, char const* argv[])
{
Point p1(1, 2);
Point p2(3, 4);
Square s1(&p1, &p2);
return 0;
}