目錄
0.前言
1.類模板基本使用
2.類模板繼承
2.1類模板繼承過程中的模板參數
情況1:父類非模板,子類為模板
情況2:父類模板,子類為非模板
情況3:父類模板,子類為模板
3.STL中的模板類分析
3.1STL中list繼承關系
3.2STL中vector繼承關系
后續補充
0.前言
本篇將整理類模板部分知識點。因為相關知識點可能較多,所以后面會將相關內容不斷補充到這篇文章中。
1.類模板基本使用
類模板基本使用是這樣的:
// 類模板繼承
#include<iostream>template <typename T>
class Base {
public:T data;Base(T val) : data(val) {}
};template <typename T>
class Derived : public Base<T> {
public:Derived(T val) : Base<T>(val) {}void print() {std::cout << "Derived data: " << this->data << std::endl;// std::cout << "Derived data: " << data << std::endl;}
};int main(void){Derived<int> d(42);d.print(); // 輸出: Derived data: 42return 0;
}
此外,還有一個很陰間的用法,類模板模板參數,它的使用大概是下面這樣的:
#include<vector>
template<typename T>
using vector = std::vector<T>;
template<typename T,template<typename U> class Con>
class Container {
public:Con<T> item;Container(T val) {item.push_back(val);std::cout << "Container initialized with value: " << val << std::endl;}void display() {for(auto & elem : item) {std::cout << elem << " ";} }
};int main(void){Container<int, vector> c(100);c.display(); // 輸出: Container holds: 100return 0;
}
2.類模板繼承
2.1類模板繼承過程中的模板參數
情況1:父類非模板,子類為模板
嚴格來說,不算類模板繼承,但是也列舉在這里。代碼如下:
class Base {
public:int data;Base(int val) : data(val) {}
};template <typename T>
class Derived : public Base{
public:Derived(T val) : Base(val) {}void print() {std::cout << "Derived data: " << this->data << std::endl;// std::cout << "Derived data: " << data << std::endl;}
};
情況2:父類模板,子類為非模板
這種情況可能不嚴謹,但是從內存角度來說,它的意思是父類對應的內存由實例化確定,子類內存是確定的。
template <typename T>
class Derived : public Base<T>{
public:Derived(int val) : Base<T>(val) {}void print() {std::cout << "Derived data: " << this->data << std::endl;// std::cout << "Derived data: " << data << std::endl;}
};
情況3:父類模板,子類為模板
這種情況是比較典型的模板類繼承,代碼如下:
template <typename U,typename T>
class Derived : public Base<T>{
public:Derived(T val) : Base<T>(val) {}void print() {std::cout << "Derived data: " << this->data << std::endl;// std::cout << "Derived data: " << data << std::endl;}
};
3.STL中的模板類分析
3.1STL中list繼承關系
下圖為GCC 8.1.0的list的繼承關系圖,你知道它的大小嗎?
如果對繼承和包含不熟悉可以移步另一篇文章:
C++繼承和包含知識及測試代碼-CSDN博客
已知條件為:
(1)空心箭頭表示繼承(is-a),實心箭頭表示包含(has-a);
(2)_List_node_base包含的兩個元素是指針類型。
(3)_M_size為 unsigned long long類型
----------------------------------------------------------分割線--------------------------------------------------------------
其實list的大小和以下這個結構體是相等的。其中兩個指針對應著鏈表(雙向)節點的中的兩個指針,另外一個對應鏈表的長度信息。在64bit編譯器中,我輸出的結果是24字節。
struct A{_List_node_base* a;_List_node_base* b;unsigned long long c;
};
更直觀的,如果對vscode熟悉的話,可以看一下debug界面。如下圖,是不是對list結構更清晰了一點呢?
3.2STL中vector繼承關系
看完了list,看下常用的vector,它相對要簡單一些,可以看出它的大小嗎?
已知條件為:
_Vector_impl包含的三個元素都是指針類型。
----------------------------------------------------------分割線--------------------------------------------------------------
同樣的,在64bit編譯器中,我輸出的結果是24字節。在vscode中,可以看到其內存布局如下圖:
后續補充
此部分由于比較復雜,后續會繼續補充!