数组四种类型
栈,堆
qDebug() << "test_stack_heap start"; Entity *entity1 = nullptr; Entity *const *p = nullptr; { MyList<Entity *> myList; entity1 = new Entity(1, "entity1"); myList.push_back(entity1); qDebug() << "myList 地址:" << &myList << ",数组指针变量地址:" << &myList.at(0) << ",数组指针变量指向的内存地址:" << myList.at(0); // 1.传值 qDebug() << "funcParam"; funcParam(myList); // 2.传指针 qDebug() << "funcParamPointer"; funcParamPointer(&myList); // 3.传援用 qDebug() << "funcParamRef"; funcParamRef(myList); p = &(myList.at(0)); qDebug()<< (**p).id(); // myList被删除前(函数体完结主动删除),能够拜访到数组内元素地址,进而取得堆内存里的entity内容
运行后果:
mylist变量存于栈内存,Entity指针变量存于栈内存(数据量大的时候QList会存数据到堆内存),Entity指针指向的Entity内容存于堆内存
生命周期完结后mylist开释,Entity指针变量开释,Entity指针指向的Entity内容不开释(需手动delete)
传参:
- 传值
将mylist的Entity指针变量拷贝复制到list里,此时,list与mylist地址不一样,list的指针变量地址与mylist的指针变量地址不一样,list的指针变量指向的内容与mylist的指针变量指向的内容一样 - 传指针
将mylist的地址作为参数传递,此时只会有地址的拷贝,list的地址与mylist的地址将会一样,指针变量的地址也一样,指针变量指向的内容地址也一样 - 传援用
传援用与传指针一样
栈,栈
qDebug() << "test_stack_stack start"; Entity const *p = nullptr; { MyList<Entity> myList; Entity entity1(1, "entity1"); myList.push_back(entity1); qDebug() << "myList 地址:" << &myList << ",数组内容地址:" << &myList.at(0); // 1.传值 qDebug() << "funcParam"; funcParam(myList); // 2.传指针 qDebug() << "funcParamPointer"; funcParamPointer(&myList); // 3.传援用 qDebug() << "funcParamRef"; funcParamRef(myList); p = &(myList.at(0)); qDebug()<< (*p).id(); // myList被删除前(函数体完结主动删除),能够拜访到数组内元素,取得数组存储的entity内容 } qDebug() << (*p).id(); //此时数组被开释,类指针被开释,无奈再通过其拜访 qDebug() << "test_stack_stack end";
运行后果:
mylist变量存于栈内存,Entity内容存于栈内存(数据量大的时候QList会存数据到堆内存),生命周期完结后mylist开释,Entity内容开释
传参:
- 传值
将mylist的Entity内容拷贝复制(会拷贝两次,一次是长期变量)到list里,此时,list与mylist地址不一样,list的内容地址与mylist的内容地址不一样 - 传指针
将mylist的地址作为参数传递,此时只会有地址的拷贝,list的地址与mylist的地址将会一样,内容地址也一样 - 传援用
传援用与传指针一样
堆,栈
qDebug() << "test_heap_stack start"; MyList<Entity> *myList = new MyList<Entity>; Entity const *p = nullptr; { Entity entity1(1, "entity1"); myList->push_back(entity1); qDebug() << "myList 地址:" << myList << ",数组内容地址:" << &myList->at(0); // 1.传值 qDebug() << "funcParam"; funcParam(*myList); // 2.传指针 qDebug() << "funcParamPointer"; funcParamPointer(myList); // 3.传援用 qDebug() << "funcParamRef"; funcParamRef(*myList); p = &(myList->at(0)); } qDebug() << (*p).id(); //删除myList前,能够拜访entity内容 delete myList; qDebug() << (*p).id(); //删除myList后,无法访问entity内容 qDebug() << "test_heap_stack end";
运行后果:
mylist变量存于堆内存,Entity内容存于栈内存(数据量大的时候QList会存数据到堆内存),mylist需手动开释(开释后Entity内容则主动开释)
传参:
- 传值
将mylist的Entity内容拷贝复制(会拷贝两次,一次是长期变量)到list里,此时,list与mylist地址不一样,list的内容地址与mylist的内容地址不一样 - 传指针
将mylist指针变量作为参数传递,此时只会有地址的拷贝,list的地址与mylist的地址将会一样,内容地址也一样 - 传援用
传援用与传指针一样
堆,堆
qDebug() << "test_heap_heap start"; MyList<Entity *> *myList = new MyList<Entity *>; Entity *entity1 = nullptr; Entity *const *p = nullptr; { entity1 = new Entity(1, "entity1"); myList->push_back(entity1); qDebug() << "myList 地址:" << myList << ",数组指针变量地址:" << &myList->at(0) << ",数组指针变量指向的内存地址:" << myList->at(0); // 1.传值 qDebug() << "funcParam"; funcParam(*myList); // 2.传指针 qDebug() << "funcParamPointer"; funcParamPointer(myList); // 3.传援用 qDebug() << "funcParamRef"; funcParamRef(*myList); p = &(myList->at(0)); } qDebug() << (**p).id(); // "删除myList前,能够拜访entity内容" delete myList; // qDebug() << (**p).id(); //"删除myList后,无法访问entity内容" qDebug() << entity1->id(); //堆内存Entity内容仍然存在 delete entity1; qDebug() << "test_heap_heap end";
运行后果:
mylist变量存于堆内存,Entity指针变量存于栈内存(数据量大的时候QList会存数据到堆内存),Entity指针指向的Entity内容存于堆内存,mylist需手动开释(开释后Entity指针变量开释,如果Entity指针指向的Entity内容不手动开释,则可能造成内存透露),Entity内容需手动开释
传参:
- 传值
将mylist的Entity指针变量拷贝复制到list里,此时,list与mylist地址不一样,list的指针变量地址与mylist的指针变量地址不一样,list的指针变量指向的内容与mylist的指针变量指向的内容一样 - 传指针
将mylist指针变量作为参数传递,此时只会有地址的拷贝,list的地址与mylist的地址将会一样,list的指针变量地址与mylist的指针变量地址一样,list的指针变量指向的内容与mylist的指针变量指向的内容一样 - 传援用
传援用与传指针一样
最初附上代码:
entity
//entity.h#ifndef ENTITY_H#define ENTITY_H#include <QDebug>#include <QString>class Entity { public: Entity(); Entity(int id, QString name); Entity(const Entity& entity); Entity& operator=(const Entity& entity); ~Entity(); int id() const; void setId(int newId); const QString& name() const; void setName(const QString& newName); void sayHello(QString text); private: int m_id; QString m_name;};#endif // ENTITY_H//entity.cpp#include "entity.h"#include <QDebug>Entity::Entity() { // qDebug() << "Entity construtor";}Entity::Entity(int id, QString name) { this->m_id = id; this->m_name = name; // qDebug() << "Entity construtor" << m_id << m_name;}Entity::Entity(const Entity &entity) { this->m_id = entity.m_id; this->m_name = entity.m_name; // qDebug() << "Entity copy" << m_id << m_name;}Entity &Entity::operator=(const Entity &entity) { if (this != &entity) { this->m_id = entity.m_id; this->m_name = entity.m_name; } // qDebug() << "Entity =" << m_id << m_name; return *this;}Entity::~Entity() { // qDebug() << "Entity delete" << m_id << m_name;}int Entity::id() const { return m_id; }void Entity::setId(int newId) { m_id = newId; }const QString &Entity::name() const { return m_name; }void Entity::setName(const QString &newName) { m_name = newName; }void Entity::sayHello(QString text) { qDebug() << "Entity SayHello!" << text; }
mylist
//mylist.h#ifndef MYLIST_H#define MYLIST_H#include <QDebug>#include <QList>#include "entity.h"template <typename T>class MyList : public QList<T> { public: MyList(); MyList(MyList *myList) { for (int i = 0; i < myList->length(); i++) { this->push_back(myList->at(i)); } } MyList(MyList &myList) { for (int i = 0; i < myList.length(); i++) { this->push_back(myList.at(i)); } } ~MyList();};template <typename T>MyList<T>::MyList() : QList<T>() { // qDebug() << "MyList constrotor";}template <typename T>MyList<T>::~MyList() { // qDebug() << "MyList delete";}#endif // MYLIST_H
mainwindow
//mainwindow.h#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include "entity.h"#include "mylist.h"QT_BEGIN_NAMESPACEnamespace Ui {class MainWindow;}QT_END_NAMESPACEclass MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); void test_stack_heap(); void test_stack_stack(); void test_heap_stack(); void test_heap_heap(); void test_funcParam(); void funcParam(MyList<Entity> list); void funcParamPointer(MyList<Entity> *list); void funcParamRef(MyList<Entity> &list); void funcParam(MyList<Entity *> list); void funcParamPointer(MyList<Entity *> *list); void funcParamRef(MyList<Entity *> &list); private: Ui::MainWindow *ui;};#endif // MAINWINDOW_H//mainwindow.cpp#include "mainwindow.h"#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // test_stack_heap(); //栈-堆 // test_stack_stack(); //栈-栈 // test_heap_stack(); //堆-栈 test_heap_heap(); //堆-堆}MainWindow::~MainWindow() { delete ui; }void MainWindow::test_stack_heap() { qDebug() << "test_stack_heap start"; Entity *entity1 = nullptr; Entity *const *p = nullptr; { MyList<Entity *> myList; entity1 = new Entity(1, "entity1"); myList.push_back(entity1); qDebug() << "myList 地址:" << &myList << ",数组指针变量地址:" << &myList.at(0) << ",数组指针变量指向的内存地址:" << myList.at(0); // 1.传值 qDebug() << "funcParam"; funcParam(myList); // 2.传指针 qDebug() << "funcParamPointer"; funcParamPointer(&myList); // 3.传援用 qDebug() << "funcParamRef"; funcParamRef(myList); p = &(myList.at(0)); qDebug() << (**p) .id(); // myList被删除前(函数体完结主动删除),能够拜访到数组内元素地址,进而取得堆内存里的entity内容 } // qDebug() // <<(**p).id();//此时数组被开释,类指针被开释,无奈再通过其拜访堆内存内容 qDebug() << entity1->id(); //堆内存Entity内容仍然存在 delete entity1; qDebug() << "test_stack_heap end";}void MainWindow::test_stack_stack() { qDebug() << "test_stack_stack start"; Entity const *p = nullptr; { MyList<Entity> myList; Entity entity1(1, "entity1"); myList.push_back(entity1); qDebug() << "myList 地址:" << &myList << ",数组内容地址:" << &myList.at(0); // 1.传值 qDebug() << "funcParam"; funcParam(myList); // 2.传指针 qDebug() << "funcParamPointer"; funcParamPointer(&myList); // 3.传援用 qDebug() << "funcParamRef"; funcParamRef(myList); p = &(myList.at(0)); qDebug() << (*p).id(); // myList被删除前(函数体完结主动删除),能够拜访到数组内元素,取得数组存储的entity内容 } qDebug() << (*p).id(); //此时数组被开释,类指针被开释,无奈再通过其拜访 qDebug() << "test_stack_stack end";}void MainWindow::test_heap_stack() { qDebug() << "test_heap_stack start"; MyList<Entity> *myList = new MyList<Entity>; Entity const *p = nullptr; { Entity entity1(1, "entity1"); myList->push_back(entity1); qDebug() << "myList 地址:" << myList << ",数组内容地址:" << &myList->at(0); // 1.传值 qDebug() << "funcParam"; funcParam(*myList); // 2.传指针 qDebug() << "funcParamPointer"; funcParamPointer(myList); // 3.传援用 qDebug() << "funcParamRef"; funcParamRef(*myList); p = &(myList->at(0)); } qDebug() << (*p).id(); //删除myList前,能够拜访entity内容 delete myList; qDebug() << (*p).id(); //删除myList后,无法访问entity内容 qDebug() << "test_heap_stack end";}void MainWindow::test_heap_heap() { qDebug() << "test_heap_heap start"; MyList<Entity *> *myList = new MyList<Entity *>; Entity *entity1 = nullptr; Entity *const *p = nullptr; { entity1 = new Entity(1, "entity1"); myList->push_back(entity1); qDebug() << "myList 地址:" << myList << ",数组指针变量地址:" << &myList->at(0) << ",数组指针变量指向的内存地址:" << myList->at(0); // 1.传值 qDebug() << "funcParam"; funcParam(*myList); // 2.传指针 qDebug() << "funcParamPointer"; funcParamPointer(myList); // 3.传援用 qDebug() << "funcParamRef"; funcParamRef(*myList); p = &(myList->at(0)); } qDebug() << (**p).id(); // "删除myList前,能够拜访entity内容" delete myList; // qDebug() << (**p).id(); //"删除myList后,无法访问entity内容" qDebug() << entity1->id(); //堆内存Entity内容仍然存在 delete entity1; qDebug() << "test_heap_heap end";}void MainWindow::funcParam(MyList<Entity> list) { qDebug() << "list 地址:" << &list << ",数组内容地址:" << &list.at(0);}void MainWindow::funcParamPointer(MyList<Entity> *list) { qDebug() << "list 地址:" << list << ",数组内容地址:" << &list->at(0);}void MainWindow::funcParamRef(MyList<Entity> &list) { qDebug() << "list 地址:" << &list << ",数组内容地址:" << &list.at(0);}void MainWindow::funcParam(MyList<Entity *> list) { qDebug() << "list 地址:" << &list << ",数组指针变量地址:" << &list.at(0) << ",数组指针变量指向的内存地址:" << list.at(0);}void MainWindow::funcParamPointer(MyList<Entity *> *list) { qDebug() << "list 地址:" << list << ",数组指针变量地址:" << &list->at(0) << ",数组指针变量指向的内存地址:" << list->at(0);}void MainWindow::funcParamRef(MyList<Entity *> &list) { qDebug() << "list 地址:" << &list << ",数组指针变量地址:" << &list.at(0) << ",数组指针变量指向的内存地址:" << list.at(0);}