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