android 源碼閱讀的C++語(yǔ)法準(zhǔn)備7 模板 文件和流 STL

模板

模板是泛型編程的基礎(chǔ),泛型編程即以一種獨(dú)立于任何特定類型的方式編寫(xiě)代碼。

模板是創(chuàng)建泛型類或函數(shù)的藍(lán)圖或公式。庫(kù)容器,比如迭代器和算法,都是泛型編程的例子,它們都使用了模板的概念。

每個(gè)容器都有一個(gè)單一的定義,比如 向量,我們可以定義許多不同類型的向量,比如 vector <int>vector <string>。

可以使用模板來(lái)定義函數(shù)和類。

函數(shù)模板

模板函數(shù)定義的一般形式如下所示:

template <class type> ret-type func-name(parameter list) {    // 函數(shù)的主體 }

在這里,type 是函數(shù)所使用的數(shù)據(jù)類型的占位符名稱。這個(gè)名稱可以在函數(shù)定義中使用。

類模板

如定義函數(shù)模板一樣,也可以定義類模板。泛型類聲明的一般形式如下所示:

template <class type> class class-name {
.
.
}

/*-----函數(shù)模版-----*/
/* T const & 是一體的,& 不是和Max一體,這表示返回類型是引用類型并且是不可修改的const類型*/
template<typename T>
inline T const &Max(T const &a, T const &b) {
    return a < b ? b : a;
}

/*-----類模版------*/
template <class T>
class Stack {
private:
    vector<T> elems;     // 元素

public:
    void push(T const&);  // 入棧
    void pop();               // 出棧
    T top() const;            // 返回棧頂元素
    bool empty() const{       // 如果為空則返回真。
        return elems.empty();
    }
};

template <class T>
void Stack<T>::push (T const& elem)
{
    // 追加傳入元素的副本
    elems.push_back(elem);
}

文件和流

數(shù)據(jù)類型 描述
ofstream 該數(shù)據(jù)類型表示輸出文件流,用于創(chuàng)建文件并向文件寫(xiě)入信息
ifstream 該數(shù)據(jù)類型表示輸入文件流,用于從文件讀取信息。
fstream 該數(shù)據(jù)類型通常表示文件流,且同時(shí)具有 ofstream 和 ifstream 兩種功能,這意味著它可以創(chuàng)建文件,向文件寫(xiě)入信息,從文件讀取信息。

打開(kāi)文件

在從文件讀取信息或者向文件寫(xiě)入信息之前,必須先打開(kāi)文件。open() 函數(shù)是 fstream、ifstream 和 ofstream 對(duì)象的一個(gè)成員。

void open(const char *filename, ios::openmode mode);

在這里,open() 成員函數(shù)的第一參數(shù)指定要打開(kāi)的文件的名稱和位置,第二個(gè)參數(shù)定義文件被打開(kāi)的模式。

模式標(biāo)志 描述
ios::app 追加模式。所有寫(xiě)入都追加到文件末尾。
ios::ate 文件打開(kāi)后定位到文件末尾。
ios::in 打開(kāi)文件用于讀取。
ios::out 打開(kāi)文件用于寫(xiě)入。
ios::trunc 如果該文件已經(jīng)存在,其內(nèi)容將在打開(kāi)文件之前被截?cái)?,即?strong>文件長(zhǎng)度設(shè)為 0。

您可以把以上兩種或兩種以上的模式結(jié)合使用。例如,如果想要以寫(xiě)入模式打開(kāi)文件,并希望截?cái)辔募?,以防文件已存在,那么您可以使用下面的語(yǔ)法:

ofstream outfile;
outfile.open("file.dat", ios::out | ios::trunc );

類似地,您如果想要打開(kāi)一個(gè)文件用于讀寫(xiě),可以使用下面的語(yǔ)法:

ifstream  afile;
afile.open("file.dat", ios::out | ios::in );

關(guān)閉文件

當(dāng) C++ 程序終止時(shí),它會(huì)自動(dòng)關(guān)閉刷新所有流,釋放所有分配的內(nèi)存,并關(guān)閉所有打開(kāi)的文件。但程序員應(yīng)該養(yǎng)成一個(gè)好習(xí)慣,在程序終止前關(guān)閉所有打開(kāi)的文件。

void close();

寫(xiě)入文件

使用流插入運(yùn)算符( << )向文件寫(xiě)入信息,就像使用該運(yùn)算符輸出信息到屏幕上一樣。唯一不同的是,在這里您使用的是 ofstreamfstream 對(duì)象,而不是 cout 對(duì)象。

讀取文件

使用流提取運(yùn)算符( >> )從文件讀取信息,就像使用該運(yùn)算符從鍵盤輸入信息一樣。唯一不同的是,在這里您使用的是 ifstreamfstream 對(duì)象,而不是 cin 對(duì)象。

#include <fstream>
#include <iostream>
using namespace std;

int main() {
    char data[100];
    //以寫(xiě)模式打開(kāi)文件
    ofstream outfile;
    outfile.open("afile.dat");

    cout << "Writing to the file" << endl;
    cout << "Enter your name: ";

    //讀取輸入數(shù)據(jù)
    cin.getline(data, 100);

    //向文件寫(xiě)入用戶數(shù)據(jù)
    outfile << data << endl;

    cout << "Enter your age: ";
    cin >> data;
    cin.ignore();

    // 再次向文件寫(xiě)入用戶輸入的數(shù)據(jù)
    outfile << data << endl;

    // 關(guān)閉打開(kāi)的文件
    outfile.close();

    // 以讀模式打開(kāi)文件
    ifstream infile;
    infile.open("afile.dat");

    cout << "Reading from the file" << endl;
    infile >> data;

    // 在屏幕上寫(xiě)入數(shù)據(jù)
    cout << data << endl;

    // 再次從文件讀取數(shù)據(jù),并顯示它
    infile >> data;
    cout << data << endl;

    // 關(guān)閉打開(kāi)的文件
    infile.close();

    return 0;
}

文件位置指針

istreamostream 都提供了用于重新定位文件位置指針的成員函數(shù)。這些成員函數(shù)包括關(guān)于 istream 的 seekg("seek get")和關(guān)于 ostream 的 seekp("seek put")。

__istream_type& seekg(pos_type);
__istream_type& seekg(off_type, ios_base::seekdir);

seekg 和 seekp 的參數(shù)通常是一個(gè)長(zhǎng)整型。第二個(gè)參數(shù)可以用于指定查找方向。

查找方向可以是 ios::beg(默認(rèn)的,從流的開(kāi)頭開(kāi)始定位),也可以是 ios::cur(從流的當(dāng)前位置開(kāi)始定位),也可以是 ios::end(從流的末尾開(kāi)始定位)。

文件位置指針是一個(gè)整數(shù)值,指定了從文件的起始位置到指針?biāo)谖恢玫?strong>字節(jié)數(shù)。下面是關(guān)于定位 "get" 文件位置指針的實(shí)例:

// 定位到 fileObject 的第 n 個(gè)字節(jié)(假設(shè)是 ios::beg)
fileObject.seekg( n );
 
// 把文件的讀指針從 fileObject 當(dāng)前位置向后移 n 個(gè)字節(jié)
fileObject.seekg( n, ios::cur );
 
// 把文件的讀指針從 fileObject 末尾往回移 n 個(gè)字節(jié)
fileObject.seekg( n, ios::end );
 
// 定位到 fileObject 的末尾
fileObject.seekg( 0, ios::end );

STL 概述

C++ STL(標(biāo)準(zhǔn)模板庫(kù))是一套功能強(qiáng)大的 C++ 模板類,提供了通用的模板類和函數(shù),這些模板類和函數(shù)可以實(shí)現(xiàn)多種流行和常用的算法和數(shù)據(jù)結(jié)構(gòu),如向量、鏈表、隊(duì)列、棧。

C++ 標(biāo)準(zhǔn)模板庫(kù)的核心包括以下三個(gè)組件:

組件 描述
容器(Containers) 容器是用來(lái)管理某一類對(duì)象的集合。C++ 提供了各種不同類型的容器,比如 deque、list、vector、map 等。
算法(Algorithms) 算法作用于容器。它們提供了執(zhí)行各種操作的方式,包括對(duì)容器內(nèi)容執(zhí)行初始化、排序、搜索和轉(zhuǎn)換等操作。
迭代器(iterators) 迭代器用于遍歷對(duì)象集合的元素。這些集合可能是容器,也可能是容器的子集。

示例演示了向量容器(一個(gè) C++ 標(biāo)準(zhǔn)的模板),它與數(shù)組十分相似,唯一不同的是,向量在需要擴(kuò)展大小的時(shí)候,會(huì)自動(dòng)處理它自己的存儲(chǔ)需求。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    // 創(chuàng)建一個(gè)向量存儲(chǔ) int
    vector<int> vec;
    int i;

    // 顯示 vec 的原始大小
    cout << "vector size = " << vec.size() << endl;

    // 推入 5 個(gè)值到向量中
    for(i = 0; i < 5; i++){
        vec.push_back(i);
    }

    // 顯示 vec 擴(kuò)展后的大小
    cout << "extended vector size = " << vec.size() << endl;

    // 訪問(wèn)向量中的 5 個(gè)值
    for(i = 0; i < 5; i++){
        cout << "value of vec [" << i << "] = " << vec[i] << endl;
    }

    // 使用迭代器 iterator 訪問(wèn)值
    vector<int>::iterator v = vec.begin();
    while( v != vec.end()) {
        cout << "value of v = " << *v << endl;
        v++;
    }

    return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,656評(píng)論 1 51
  • 重新系統(tǒng)學(xué)習(xí)下C++;但是還是少了好多知識(shí)點(diǎn);socket;unix;stl;boost等; C++ 教程 | 菜...
    kakukeme閱讀 20,418評(píng)論 0 50
  • 一、基礎(chǔ)知識(shí):1、JVM、JRE和JDK的區(qū)別:JVM(Java Virtual Machine):java虛擬機(jī)...
    殺小賊閱讀 2,553評(píng)論 0 4
  • 3. 類設(shè)計(jì)者工具 3.1 拷貝控制 五種函數(shù)拷貝構(gòu)造函數(shù)拷貝賦值運(yùn)算符移動(dòng)構(gòu)造函數(shù)移動(dòng)賦值運(yùn)算符析構(gòu)函數(shù)拷貝和移...
    王偵閱讀 2,062評(píng)論 0 1
  • 一定要記住這個(gè)夏天的溫度和對(duì)這個(gè)溫度的感覺(jué),潮濕不堪悶熱難當(dāng),驕陽(yáng)烈烈,地如過(guò)火,不至于到了詛咒三九嚴(yán)寒時(shí)有懷念酷...
    東箭閱讀 259評(píng)論 0 3

友情鏈接更多精彩內(nèi)容