... Я знаю, что он должен храниться в куче.
Во-первых, пожалуйста прочитайте это объяснение того, почему предпочтительнее говорить о автоматических и динамических временах жизни объектов, а не стеке / куче.
Во-вторых, этот объект не размещен ни динамически, ни в куче. Вы можете сказать, потому что динамическое распределение использует выражение new
или библиотечную функцию, такую как malloc
, calloc
или, возможно, mmap
. Если у вас нет ни одного из них (и вы почти никогда не должны), это не динамично.
Вы возвращаете что-то по значению, так что время жизни этой вещи определенно автоматическое.
Когда точка создается, когда она уничтожается?
Если вы напишите полный набор конструкторов копирования / перемещения и операторов присваивания, а также деструктор, вы можете просто установить в них точки останова в отладчике и см. , где они вызываются. Или пусть все они напечатают свои указатель this
и входные аргументы (т. Е. Исходный объект, который перемещается или копируется).
Однако, поскольку мы знаем, что объект автоматический, ответ прост - когда он выходит из области видимости.
Должен ли я использовать Point & p или Point p для возврата Point :: NewCartesian?
Определенно, второе: первое возвращает ссылку на объект с автоматическим временем жизни в области действия функции NewCartesian
, означая, что объект, на который ссылаются, уже мертв к моменту, когда вызывающая сторона получает ссылку.
Наконец, этот код
Point& p = Point::NewCartesian(5, 10);
странно - из-за чтения кода сложно определить время жизни Point
, на которое ссылается p
. Это может быть некоторый статический / глобальный / другой объект с динамическим временем жизни, для которого NewCartesian
возвращает ссылку, или (как на самом деле), вы можете привязывать ссылку к анонимному временному объекту. Нет смысла писать так вместо
Point p = Point::NewCartesian(5, 10);
или просто передавая временную прямую к push_back
, как в вашем коде с комментариями.
Кстати, дизайн Point
очень странный. Он имеет открытые члены данных, но закрытый конструктор и открытый статический метод, который просто вызывает конструктор. Вы можете полностью опустить конструктор и статический метод и просто использовать агрегатную инициализацию или опустить статический метод и сделать конструктор общедоступным.