共计 9312 个字符,预计需要花费 24 分钟才能阅读完成。
数组四种类型
栈,堆
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_NAMESPACE
namespace Ui {class MainWindow;}
QT_END_NAMESPACE
class 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);
}
正文完