共享智能指针编程实验
共享智能指針編程實驗
- 基本知識
- shared_ptr與make_shared
- initializer_list
- 自定義的StrBlob類
- const限定符
- 示例代碼
- my_StrBlob.h
- main.cpp
- 運行結果
本文是本人大一期間在校學習C++課程時所撰寫的實驗報告的摘錄,由于剛上大學,剛接觸計算機編程方面的相關知識,故可能會有很多不足甚至錯誤的地方,還請各位看官指出及糾正。
本文所涉及到的“教材”指:
電子工業出版社《C++ Primary中文版(第5版)》
如需轉載或引用請標明出處。
基本知識
shared_ptr與make_shared
關于智能指針shared_ptr的大致知識點已在上一篇文章中有所介紹,這次不同的是,不使用關鍵字new的返回值賦給shared_ptr對象,而是使用標準庫函數make_shared。
make_shared與shared_ptr一樣定義在memory頭文件中,此函數在動態內存中分配一個對象并初始化它,返回指向此對象的shared_ptr。
當要使用make_shared時,必須指定想要創建的對象的類型。定義方式與模板類相同,在函數名后跟一個尖括號,在其中給出類型:
shared_ptr<int> p1 = make_shared<int> (42); //指向一個值為42的int的shared_ptr shared_ptr<string> p2 = make_shared<string> (10, ‘9’); //p2指向一個值為”9999999999”的stringmake_shared常與shared_ptr配套使用。
initializer_list
如果函數的實參數量未知但是全部實參的類型都相同, 我們可以使用initializer_list類型的形參。initializer_list是一種標準庫類型,用于表示某種特定類型的值的數組。其定義在同名的頭文件中。以下面這個函數聲明為例:
StrBlob(initializer_list<string> list); //有可變形參的構造函數聲明該函數是StrBlob的構造函數之一,initializer_list也是一種模板類型,其尖括號內的類型及其列表內所含元素的類型,該列表名稱為list。可以像這樣使用該函數:
StrBlob b2({ "China", "America", "Japan" });這樣就聲明了一個StrBlob類b2,其指向的vector中含有三個元素,其中方括號內的元素數量是任意的,但必須都是string類型且放在花括號內。
更多關于initializer_list的操作詳見教材P198表6.1。
自定義的StrBlob類
StrBlob是一個自定義的類。從某種程度上來說類與結構體幾乎是一模一樣的,只有細小的差別。在類里聲明的變量都是屬于該類的成員,在類里聲明的變量都是屬于該類的成員函數。成員函數既可以在類內定義,也可以在類外定義,在類內定義的函數默認數內聯函數,當然,類外定義的函數也可通過inline限定符使其成為內聯函數。
每個類都分別定義了它的對象被初始化的方式,類通過一個或幾個特殊的成員函數來控制其對象的初始化過程,這些函數都叫做構造函數。構造函數的任務是初始化類對象的數據成員,無論何使只要類的對象被建創,就會執行構造函數。構造函數的名字和類名相同。和其他函數不一樣的是,構造函數沒有返回類型。除此之外,構造函數也有一個(可能為空的)參數列表和一個(可能為空的)函數體。類可以包含多個構造函數,和其他重載函數類似。例如:
//定義無形參的構造函數 StrBlob::StrBlob() :data(make_shared<vector<string>>()) { } //定義有可變形參的構造函數 StrBlob::StrBlob(initializer_list<string> list) : data(make_shared<vector<string>>(list)) { }這兩個函數的函數體為空,是因為其冒號和花括號之間的構造函數初始值列表就已經完成了為類成員賦值的工作。第二個構造函數的定義與下面是等價的:
StrBlob::StrBlob(initializer_list<string> list) {data = make_shared<vector<string>>(list); }另外,在類中定義在public說明符之后的成員在整個程序內可被訪問,public成員定義類的接口。定義在private說明符之后的成員可以被類的成員函數訪問,但是不能被使用該類的代碼訪問,private部分封裝了類的實現細節。
const限定符
const常量限定符的作用在不同的地方有所不同,但都突出在“不能改變”的特性上。用在變量前面,說明該變量不能被改變;用在指針上,說明該指針不能改變其所指向的對象或該指針不能指向別的對象(要看const限定符的位置);用在函數前面,說明該函數返回一個常量對象。
這里比較特殊的是,在成員函數的形參列表后加const限定符,意為修改隱式this指針的類型,使其不能改變其所指的對象。
this是一個額外的隱式參數,成員函數通過它來訪問調用它的那個對象。在成員函數內部,我們可以直接使用調用該函數的對象的成員,而無須通過成員訪問運算符來做到這一點,因為this所指的正是這個對象。任何對類成員的直接訪問都被看作this的隱式應用。
示例代碼
my_StrBlob.h
#ifndef MY_STRBLOB_H #define MY_STRBLOB_H #include <vector> #include <string> #include <memory> //包含標準庫類型initializer_list,以使用有可變形參的函數 #include <initializer_list> //包含并使用一些標準庫異常 #include <stdexcept>using namespace std;//定義StrBlob類 class StrBlob { //public的成員可被整個程序使用 public:typedef vector<string>::size_type size_type; //定義vector<string>的size_type類型為size_typeStrBlob(); //無形參的構造函數聲明StrBlob(initializer_list<string> list); //有可變形參的構造函數聲明size_type size() const { return data->size(); } //定義StrBlob的成員函數sizebool empty() const { return data->empty(); } //定義StrBlob的成員函數empty//添加和刪除元素的操作void push_back(const string& t) { data->push_back(t); } //定義StrBlob的成員函數push_backvoid pop_back(); //StrBlob的成員函數pop_back的聲明//訪問元素的操作string& front(); //StrBlob的成員函數front的聲明const string& front() const; //const版本的StrBlob的成員函數front的聲明string& back(); //StrBlob的成員函數back的聲明const string& back() const; //const版本的StrBlob的成員函數back的聲明//private的成員只能被類的成員函數訪問 private: shared_ptr<vector<string>> data; //該類只有一個成員:指向存儲string的vector的智能指針void check(size_type i, const string& msg) const; //如果data[i]不合法,拋出一個異常,顯示msg };StrBlob::StrBlob() :data(make_shared<vector<string>>()) { } //定義無形參的構造函數 StrBlob::StrBlob(initializer_list<string> list) : data(make_shared<vector<string>>(list)) { } //定義有可變形參的構造函數void StrBlob::check(size_type i, const string& msg) const //check函數的定義 {if (i >= data->size()) //如果i超出vector的范圍throw out_of_range(msg); //則拋出異常 }string& StrBlob::front() //普通版本的front函數 {check(0, "front on empty StrBlob"); //如果vector為空,則check拋出一個異常return data->front(); //返回data的成員函數front的返回值 }const string& StrBlob::front() const //const版本的front函數 { check(0, "front on empty StrBlob"); //如果vector為空,則check拋出一個異常return data->front(); //返回data的成員函數front的返回值 }string& StrBlob::back() //普通版本的back函數 {check(0, "back on empty StrBlob"); //如果vector為空,則check拋出一個異常return data->back(); //返回data的成員函數back的返回值 }const string& StrBlob::back() const //const版本的back函數 {check(0, "back on empty StrBlob"); //如果vector為空,則check拋出一個異常return data->back(); //返回data的成員函數back的返回值 }void StrBlob::pop_back() //定義SrtBlob的成員函數pop_back {check(0, "pop_back on empty StrBlob"); //如果vector為空,則check拋出一個異常data->pop_back(); //返回data的成員函數pop_back的返回值 }#endifmain.cpp
#include <iostream> #include "my_StrBlob.h" //包含自定義的頭文件用雙引號int main(void) {StrBlob b1; //用無形參的構造函數初始化StrBlob類型b1{StrBlob b2({ "China", "America", "Japan" }); //用有可變形參的構造函數初始化StrBlob類型b2b1 = b2; //將b2的值賦給b1b2.push_back("France"); //在b2末尾添加元素“France”cout << b2.size() << endl; //輸出b2}//b2的作用域結束,其智能指針的的計數器減一cout << b1.size() << endl; //使用自定義的成員函數size輸出b1的大小cout << b1.front() << " " << b1.back() << endl; //使用自定義的成員函數front、back輸出b1的首位兩個元素b1.pop_back(); //刪除b1的尾元素const StrBlob b3 = b1; //復制一份const的b1給b3,b1智能指針的計數器加一 cout << b3.front() << " " << b3.back() << endl; //使用const版本的自定義的成員函數front、back輸出b3的首位兩個元素system("pause");return 0; }運行結果
總結
以上是生活随笔為你收集整理的共享智能指针编程实验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 动态内存的基本功能和使用
- 下一篇: weak_ptr指针编程实验