我正在尝试测试数据的定位和销毁方式和位置。对于下面的示例代码:
使用 NewCartesian 方法创建并返回一个新点。我知道它应该存储在堆中。当它被推回 vector 时,点内容的内存是否被复制到一个新的点结构中?还是将其存储为 this 指针的引用?
点什么时候创建,什么时候销毁?点数用完后需要销毁吗?还是当它们不再有用时就被销毁了?例如,如果 main 是另一个函数,则 vector 在完成后将没有用。
根据上面的回答,什么时候使用对象引用比较好?我应该使用 Point& p 还是 Point p 来返回 Point::NewCartesian?
#define _USE_MATH_DEFINES #include <iostream> #include <cmath> using namespace std; struct Point { private: Point(float x, float y) : x(x), y(y) {} public: float x, y; static Point NewCartesian(float x, float y) { return{ x, y }; } }; int main() { vector<Point> vectorPoint; for (int i = 0; i < 10000; i++) { Point& p = Point::NewCartesian(5, 10); vectorPoint.push_back( p ); // vectorPoint.push_back( Point::NewCartesian(5, 10) ); Point& p2 = Point::NewPolar(5, M_PI_4); } cout << "deneme" << endl; getchar(); return 0; }
谢谢你的帮助,
干杯,
最佳答案
... I know that it should be stored in heap.
首先请read this解释为什么最好谈论自动和动态对象生命周期,而不是堆栈/堆。
其次,该对象既不是动态分配的,也不是在堆上的。你可以看出是因为动态分配使用了 new
表达式,或者像 malloc
、calloc
或者可能是 mmap
这样的库函数>。如果您没有任何这些(而且您几乎从不应该),它就不是动态的。
您按值返回某些东西,因此该东西的生命周期绝对是自动的。
When the point is created, when is it destroyed?
如果您编写了完整的复制/移动构造函数和赋值运算符集,再加上一个析构函数,您只需在调试器中设置断点,然后查看它们在何处被调用。或者,让它们都打印出它们的 this
指针和输入参数(即,正在移动或复制的源对象)。
但是,由于我们知道该对象是自动的,所以答案很简单 - 当它超出范围时。
Should I use Point& p or Point p for the return of Point::NewCartesian?
绝对是第二种:第一种返回对 NewCartesian
函数范围内具有自动生命周期的对象的引用,这意味着在调用者获取引用时引用的对象已经死亡。
最后是这段代码
Point& p = Point::NewCartesian(5, 10);
很奇怪 - 很难通过阅读代码来确定 p
引用的 Point
的生命周期。它可能是一些具有动态生命周期的静态/全局/其他对象,NewCartesian
返回一个引用,或(实际情况如此)您可以将引用绑定(bind)到一个匿名临时。以这种方式编写它而不是
Point p = Point::NewCartesian(5, 10);
或者像您注释的代码一样,直接将临时文件直接传递给 push_back
。
顺便说一句,Point
的设计很奇怪。它有公共(public)数据成员,但有一个私有(private)构造函数和一个只调用构造函数的公共(public)静态方法。您可以完全省略构造函数和静态方法而只使用聚合初始化,或者省略静态方法并将构造函数公开。
关于c++ - C++中的内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52152271/