1. 程式人生 > 其它 >【C++】模板類的使用以及例項

【C++】模板類的使用以及例項

技術標籤:C++ubuntuc++

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",
    ],
)