Почему эти точки уничтожены трижды?

Вот код

#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)

Я ожидаю, что каждая точка будет уничтожена дважды, но вместо этого они уничтожаются трижды. Зачем?

1

Решение

Так как

Square(Point p1, Point p2)

принимает аргументы, передаваемые по значению, которое создает копию параметров, которые вы передаете ему. Так что у тебя есть

  1. Исходные параметры
  2. Копии переданы Square конструктор
  3. Переменные-члены экземпляра Square вы создаете

3 экземпляра.

4

Другие решения

вы копируете их в конструктор

пытаться 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

Этот конструктор

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)

означает, что сначала был создан элемент данных upperleft, потому что он был объявлен до того, как был создан нижний правый, а затем нижний правый. Снова они удаляются в обратном порядке.

И наконец эти две строки

Point destroyed: (3, 4)
Point destroyed: (1, 2)

означает, что сначала точка (1, 2) была создана, потому что она определена до создания точки (3, 4) в главной, а затем точка (3, 4). Они удаляются в обратном порядке.

2

Уничтожить дважды, используя ссылки:

#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;
}
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector