【C++】模板類的使用以及例項
阿新 • • 發佈:2021-01-21
1. 前言
模板類是用來生成類的藍圖的。通過一個模板,可以節省大量的程式碼空間和提高開發的效率,本文章將會就模板類舉例進行一個簡單的例項。
2. 用模板類實現一個簡單的vector
程式碼目錄結構如下:
├── main
│ ├── BUILD
│ ├── main.cc
│ └── myvector.h
└── WORKSPACE
2.1 模板類myvector.h的程式碼如下
注意: 模板類的定義和宣告不建議分離編譯,否則可能在編譯時會導致連結錯誤,故myvector的宣告和實現都定義在同一個檔案當中。
// 檔名:myvector.h
// Copyright [2021] <Copyright Ziliu>
#pragma once
// #include <cmath>
#include <iostream>
#include <memory>
#include <string>
#include <utility>
#include <vector>
// 模板類的宣告和定義要放在同一個原始檔當中
template <typename T> class MyVector {
public:
// vector的型別
typedef T value_type;
// vector 的 size 的型別
typedef typename std::vector<T>::size_type size_type;
// 建構函式
MyVector();
// 拷貝構造
MyVector(std::initializer_list<T> il);
// Vector中元素的個數
// 通過把類成員函式宣告為const以表明它們不修改類物件。
size_type size() const {return data->size();}
bool empty() const {return data->empty();}
// 新增和刪除元素
void push_back(const T& t) {data->push_back(t);}
// 當臨時值為右值, 使用move可以降低空間代價
void push_bash(T &&t) {data->push_back(std::move(t));}
void pop_back();
// 元素訪問
T& back();
T& operator[](size_type i);
private:
std::shared_ptr<std::vector<T>> data;
// 若data[i]無效,則丟擲msg
void check(size_type i, const std::string& msg) const;
};
template <typename T>
MyVector<T>::MyVector():data(std::make_shared<std::vector<T>>()) {
}
// 拷貝構造,利用引數il來初始化此vector
template <typename T>
MyVector<T>::MyVector(std::initializer_list<T> il)
:data(std::make_shared<std::vector<T>>(il)) {
}
template <typename T>
void MyVector<T>::pop_back() {
check(0, "pop_back on empty vector.");
data->pop_back();
}
template <typename T>
T& MyVector<T>::back() {
check(0, "back on empty vector.");
return data->back();
}
template <typename T>
T& MyVector<T>::operator[](size_type i) {
check(i, "subscript out of range.");
return (*data)[i];
// return data[i];
}
// 檢查輸入index對應的位置是否有元素存在
template <typename T>
void MyVector<T>::check(size_type i, const std::string& msg) const {
if (i >= data->size()) {
throw std::out_of_range(msg);
}
}
2.2 main.cc的程式碼如下
// 檔名: main.cc
// Copyright [2021] <Copyright Ziliu>
#include <cmath>
#include <iostream>
#include "main/myvector.h"
int main() {
MyVector<int> vec;
// push_back
vec.push_back(1);
std::cout << vec[0] << std::endl;
// back
std::cout << vec.back() << std::endl;
// pop_back
vec.pop_back();
std::cout << vec.size() << std::endl;
return 0;
}
2.3 命令列直接編譯
g++ main.cc -o test -std=c++17
2.4 bazel的方式編譯
// BUILD檔案的編寫
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
cc_library(
name = "myvector",
hdrs = ["myvector.h"],
)
cc_binary(
name = "main",
srcs = ["main.cc"],
deps = [
"//main:myvector",
],
)