網站首頁 編程語言 正文
案例要求
可以對內置數據類型以及自定義數據類型的數據進行存儲
將數組中的數據存儲到堆區
構造函數中可以傳入數組的容量
提供對應的拷貝構造函數以及operator=防止淺拷貝問題
提供尾插法和尾刪法對數組中的數據進行增加和刪除
可以通過下標的方式訪問數組中的元素
可以獲取數組中當前元素個數和數組的容量
完成步驟
1、封裝數組類屬性并完成有參構造以及析構函數
#pragma once
#include<iostream>
using namespace std;
template<class T>
class Arrays
{
private:
T* arr;//數組arr存放T類型的數據
int capacity;//數組容量
int size;//數組大小
public:
Arrays(int capacity)
{
this->capacity = capacity;
this->size = 0;
this->arr = new T[this->capacity];
}
~Arrays()
{
if (this->arr != NULL)
{
delete []this->arr;
this->arr = NULL;
}
}
};
我把自己的這個數組類模板放到一個.hpp文件里,方便測試的時候調用。代碼第一行是為了防止頭文件重復包含,template里面的T就是數組的數據類型,根據調用時不同的指定存放不同類型的數據。將數組arr以及數組容量和大小進行封裝,寫在私有權限下即可 。然后提供該類的有參構造,參數列表傳入的是數組容量,有參構造初始化了數組的容量以及大小并將數組開辟到了堆區。析構函數就是來清理堆區數據,如果我們開辟的堆區數組不為空,那就清理掉并將其指向NULL,這樣可以防止野指針出現,避免異常。
2、提供對應的深拷貝構造函數防止調用析構時出錯
Arrays(const Arrays& p)
{
this->capacity = p.capacity;
this->size = p.size;
this->arr = new T[p.capacity];
for (int i = 0; i < this->size; i++)
{
this->arr[i] = p.arr[i];
}
}
如果不提供深拷貝,那么編譯器就會有:this->arr=p->arr 這行代碼 ,那么一旦我們調用編譯器提供的淺拷貝,當運行到析構函數時,就會出現重復刪除地址的情況,必然會出現程序錯誤。所以我們要自己提供深拷貝構造函數,將上面的代碼改為 this->arr= new T[p.capacity] ,這樣調用析構的時候各自刪除各的堆區數據,不會出現上述情況。最后利用for循環將傳進來的對象的數據賦值給新開辟的數組。
3、重載類內的賦值運算符防止淺拷貝問題出現
Arrays& operator=(const Arrays& p)
{
if (this->arr!=NULL)
{
delete []this->arr;
this->arr = NULL;
this->capacity = 0;
this->size = 0;
}
//深拷貝過程
this->capacity = p.capacity;
this->size = p.size;
this->arr = new T[this->capacity];
for (int i = 0; i < p.size; i++)
{
this->arr[i] = p.arr[i];
}
return *this;
}
當數組數據是對象的類型時,不能簡單的將數組進行賦值操作,因為也牽扯到直接賦值出現一樣的數組地址的情況,存在著深淺拷貝問題。賦值的時候是將傳入參數的數據賦值給自己,因此先把自己的屬性清空,然后就是深拷貝的實現了。最后返回的是*this,this指針能夠指向不同成員屬性,那么*this就是對象本身,然后看到返回值類型是對象引用,這樣就可以實現對象間的連續賦值了。
4、提供尾部插入和刪除的方法
void insert_Arrays(const T&value)
{
if (this->capacity == this->size)
{
return;
}
this->arr[size] = value;
this->size++;
}
void delete_Arrays()
{
if (this->size == 0)
{
return;
}
this->size--;
}
尾插過程:先判斷數組是否已經滿了,如果不滿就將形參賦值給當前數組最后一個下標的位置,然后更新數組下標,這樣就能保證每次插入的數據都在數組末尾。?
尾刪的實現:先判斷數組是否為空,不為空的時候直接把數組大小減一即可,讓編譯器訪問不到當前的最后一個數組元素。注意尾刪的只是數據的指針,數組的地址并未刪除。
5、重載[]得到數組中對應下標的數據信息
T& operator[](int index)
{
return this->arr[index];
}
如果數組內容是對象類型,是不存在對象數組的,所以要對[]運算符進行重載。返回值類型為數據類型的引用,也就是具體的數組內的值,傳進去的整型參數就是數組下標。
6、提供get方法獲取當前數組容量及大小
int getSize()
{
return this->size;
}
int getCapacity()
{
return this->capacity;
}
這里就是經典的get方法了,返回對應封裝的成員屬性 ,不做多解釋。
7、提供打印函數測試基本數據類型和自定義數據類型的存儲
#include"arrays.hpp"
class Hero
{
friend void printHero(Arrays<Hero>&hero);
private:
string name;
string position;
public:
Hero() {}
Hero(string name, string position)
{
this->name = name;
this->position = position;
}
};
void printArrays(Arrays<int>arr)
{
for (int i = 0; i < arr.getSize(); i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
void printHero(Arrays<Hero>&hero)
{
for (int i = 0; i < hero.getSize(); i++)
{
cout << "姓名:"<<hero[i].name<<" 位置:"<<hero[i].position<<endl;
}
}
void test()
{
cout << "普通類型數組測試:" << endl;
cout << "輸入數組容量為:" ;
int n = 0; cin >> n;
Arrays<int> array(n);
cout << "輸入數據:";
for (int i = 0; i < array.getCapacity(); i++)
{
int value = 0;
cin >> value;
array.insert_Arrays(value);
}
cout << "打印數組信息:"<<endl;
printArrays(array);
array.delete_Arrays();
cout << "刪除一次尾部數據后打印數組信息:" << endl;
printArrays(array);
}
void test1()
{
cout << "自定義類型數組測試:" << endl;
Hero h1("火舞","中單");
Hero h2("韓信","打野");
Hero h3("桑啟","游走");
Hero h4("守約","發育");
Hero h5("關羽","對抗");
Arrays<Hero> array(5);
array.insert_Arrays(h1);
array.insert_Arrays(h2);
array.insert_Arrays(h3);
array.insert_Arrays(h4);
array.insert_Arrays(h5);
printHero(array);
array.delete_Arrays();
cout << "刪除一次尾部數據后打印數組信息:"<<endl;
printHero(array);
}
首先引入之前封裝的數組類頭文件,提供printArrays和printHero函數來進行數組信息的打印,test和test1函數分別是整型數組和對象數組的測試。接下來看運行效果。
運行效果:
原文鏈接:https://blog.csdn.net/m0_58618795/article/details/125592238
相關推薦
- 2023-01-03 Qt學習之容器類的使用教程詳解_C 語言
- 2022-07-09 Python?操作?Excel?之?openpyxl?模塊_python
- 2022-04-12 python關閉print輸出信息詳情_python
- 2022-11-17 有意思的數據結構默克樹?Merkle?tree應用介紹_其它綜合
- 2022-04-04 elementui組件select選擇不中的問題(組件select選擇器無法顯示選中的內容)
- 2022-09-21 Python腳本開發中的命令行參數及傳參示例詳解_python
- 2022-11-12 Python?sklearn分類決策樹方法詳解_python
- 2022-07-27 shell腳本中一鍵部署zookeeper集群服務的方法_linux shell
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支