局部变量元素加入成员变量QList后,局部变量出了作用域后,为什么QList仍然可以获取元素的值(转)
问题
问题:现有一个成员变量QList,在函数中定义了一个局部变量的对象,并将该局部变量加入到QList中。当函数运行结束,局部变量也就出了作用域,这时,由于局部变量只是一个普通对象,而不是指针,所以,应该被销毁。但是,我们在外面仍然可以通过QList对象来访问之前加入进来的数据,这是为什么?
实验
#include <QApplication> #include "mainwindow.h" #include <QDebug> #include <QLabel> #include <QString> struct tagTEST { int a; QLabel *x; }; QList testFunc() { QList testList; tagTEST tmp; qDebug()<<"before add list:"; for(int i=0; i<10; i++) { tmp.a = i; tmp.x = new QLabel(QString::number(i)); testList.append(tmp); qDebug()<<i<<" a value:"<<tmp.a<<" x value:"<<tmp.x; } qDebug()<<"before add list size:"<<testList.size(); return testList; } int main(int argc,char *argv[]) { QFont f("ZYSong18030",10); QApplication::setFont(f); QApplication app(argc,argv); QList list = testFunc(); int size = list.size(); int i; qDebug()<<"after add list:"; qDebug()<<"after add list size:"<<size; for(i=0; i<size; i++) { qDebug()<<i<<" a value:"<<list[i].a<<" x value:"<<list[i].x; } MainWindow *mainwindow = new MainWindow(); mainwindow->show(); return app.exec(); }
运行结果
before add list: 0 a value: 0 x value: QLabel(0x3cad0) 1 a value: 1 x value: QLabel(0x3cd30) 2 a value: 2 x value: QLabel(0x3cbf0) 3 a value: 3 x value: QLabel(0x3cb90) 4 a value: 4 x value: QLabel(0x3ccf0) 5 a value: 5 x value: QLabel(0x3cd10) 6 a value: 6 x value: QLabel(0x3cd90) 7 a value: 7 x value: QLabel(0x3ca90) 8 a value: 8 x value: QLabel(0x3cdd0) 9 a value: 9 x value: QLabel(0x3cc90) before add list size: 10 after add list: after add list size: 10 0 a value: 0 x value: QLabel(0x3cad0) 1 a value: 1 x value: QLabel(0x3cd30) 2 a value: 2 x value: QLabel(0x3cbf0) 3 a value: 3 x value: QLabel(0x3cb90) 4 a value: 4 x value: QLabel(0x3ccf0) 5 a value: 5 x value: QLabel(0x3cd10) 6 a value: 6 x value: QLabel(0x3cd90) 7 a value: 7 x value: QLabel(0x3ca90) 8 a value: 8 x value: QLabel(0x3cdd0) 9 a value: 9 x value: QLabel(0x3cc90)
得出结论
说明append函数在内部进行了数据的复制,并且这种复制只是浅拷贝,因为list中每个元素的x指针和tmp中的指针地址一样,说明只是进行了浅拷贝。
图中,从刚开始,在函数中创建tmp元素时,分别在堆和栈上分别创建了数据,加入list之后,将原来tmp中的在栈上面的元素进行了浅拷贝,x指向的依旧是tmp中的那个内存,但是,元素添加进list之后,元素的作用域扩大了,因此,当函数运行结束后,tmp被销毁,但tmp所指向的内存空间依旧在,我们依然在外面通过list访问中的数据
http://www.lgwimonday.cn/archives/1397
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异