数组四种类型

栈,堆

  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)

传参:

  1. 传值
    将mylist的Entity指针变量拷贝复制到list里,此时,list与mylist地址不一样,list的指针变量地址与mylist的指针变量地址不一样,list的指针变量指向的内容与mylist的指针变量指向的内容一样
  2. 传指针
    将mylist的地址作为参数传递,此时只会有地址的拷贝,list的地址与mylist的地址将会一样,指针变量的地址也一样,指针变量指向的内容地址也一样
  3. 传援用
    传援用与传指针一样

栈,栈

  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内容开释

传参:

  1. 传值
    将mylist的Entity内容拷贝复制(会拷贝两次,一次是长期变量)到list里,此时,list与mylist地址不一样,list的内容地址与mylist的内容地址不一样
  2. 传指针
    将mylist的地址作为参数传递,此时只会有地址的拷贝,list的地址与mylist的地址将会一样,内容地址也一样
  3. 传援用
    传援用与传指针一样

堆,栈

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内容则主动开释)

传参:

  1. 传值
    将mylist的Entity内容拷贝复制(会拷贝两次,一次是长期变量)到list里,此时,list与mylist地址不一样,list的内容地址与mylist的内容地址不一样
  2. 传指针
    将mylist指针变量作为参数传递,此时只会有地址的拷贝,list的地址与mylist的地址将会一样,内容地址也一样
  3. 传援用
    传援用与传指针一样

堆,堆

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内容需手动开释

传参:

  1. 传值
    将mylist的Entity指针变量拷贝复制到list里,此时,list与mylist地址不一样,list的指针变量地址与mylist的指针变量地址不一样,list的指针变量指向的内容与mylist的指针变量指向的内容一样
  2. 传指针
    将mylist指针变量作为参数传递,此时只会有地址的拷贝,list的地址与mylist的地址将会一样,list的指针变量地址与mylist的指针变量地址一样,list的指针变量指向的内容与mylist的指针变量指向的内容一样
  3. 传援用
    传援用与传指针一样

最初附上代码:

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);}