我有这个伪代码。此代码可能不是100%正确。我的问题是当你使用堆声明一个对象?这是访问以下数据的正确方法。这意味着如果在堆上声明某些东西,还应该在堆上声明InfoMap吗?我知道两者都可以工作,这是否意味着编译器会找出处理这个问题的最佳方法?
class InfoMap
{
InfoMap(){}
QString name;
int age;
}
class InfoData
{
InfoMap RetrieveInfoList()
{
InfoMap map;
map.name = "name1";
map.age = 21;
return map;
}
InfoMap* RetrieveInfoList2()
{
InfoMap *map = new InfoMap();
map->name = "name1";
map->age = 21;
return map;
}
}
在使用InfoData的类中
void SomeClass::RetrieveData1()
{
InfoData *data = new InfoData();
InfoMap *map = data->RetrieveInfoList();
qDebug() << map->name << map->age;
}
void SomeClass::RetrieveData2()
{
InfoData *data = new InfoData();
InfoMap map = data->RetrieveInfoList2();
qDebug << map.name << map.age;
}
答案 0 :(得分:1)
不,你不必这样做。但是,为了防止内存泄漏,您必须最终在您使用delete
分配的所有内容上调用new
。在堆栈上创建对象之间的区别:
InfoData data;
堆:
InfoData *data = new InfoData();
是对象的生命周期。一旦超出范围,堆栈上的对象就会被销毁。只要没有delete
调用,堆上的对象就不会被销毁。因此,如果你忘记这样做,你就会泄漏记忆。
至于你的代码,你没有理由使用指针/ new
,你应该只使用堆栈存储:
class InfoMap
{
public:
InfoMap()
{
}
QString name;
int age;
};
class InfoData
{
public:
InfoMap RetrieveInfoList()
{
InfoMap map;
map.name = "name1";
map.age = 21;
return map;
}
};
In a class that uses InfoData
void SomeClass::RetrieveData()
{
InfoData data;
InfoMap map = data.RetrieveInfoList();
qDebug() << map.name << map.age;
}
这样,编译器就可以完成对象的破坏。
如果你觉得需要动态分配,你应该总是更喜欢原始new
/ delete
上的智能指针。
答案 1 :(得分:0)
我的问题是当您使用堆声明对象时。
通常需要传递或返回指向(新创建的)对象的指针。或者也许如果它们太大而无法叠加。
在所有其他情况下,可以避免在堆上分配对象。这也消除了delete
的需要,并避免了内存泄漏。
这是否意味着编译器将找出最佳处理方式 此?
在这种情况下,编译器会执行您要求它执行的操作。
答案 2 :(得分:0)
这两种解决方案都很好并且可行。他们之间的区别是:
1)在第一种情况下(当你在堆栈上分配一个InfoMap对象RetrieveInfoList函数然后你返回它)在return语句中,InfoMap对象的复制构造函数将被调用,原始对象的副本将是返回
2)在第二种情况下,一个InfoMap对象在堆上被淘汰,并且将返回它的一个poiter。
所以主要区别在于,在第一种情况下,您获得了对象的副本,在第二种情况下,您获得了原始对象。在您的情况下,考虑到InfoMap的结构,只是性能问题(在第一种情况下是执行的附加副本)。但是,如果InfoData包含一个无法通过默认复制构造函数正确处理的资源,则代码在两种情况下的行为相同。
答案 3 :(得分:0)