日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++ why can't class template hide its implementation in cpp file?

發(fā)布時間:2023/12/9 c/c++ 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ why can't class template hide its implementation in cpp file? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

類似的問題還有: why can't class template use Handle Class Pattern to hide its implementation? || why there are linker problems (undefined reference) to my class template?

我出現(xiàn)問題的源碼(見main.cpp,Stack.h,Stack.cpp)(本來是準備用來展示Handle Class Pattern如何實現(xiàn)implementation-hiding),報錯如下:

?

問題的本質(zhì)&解決辦法:

http://stackoverflow.com/questions/8752837/undefined-reference-to-template-class-constructor

http://www.parashift.com/c++-faq-lite/templates-defn-vs-decl.html

http://stackoverflow.com/questions/5417465/separating-template-interface-and-implementation-in-c

http://stackoverflow.com/questions/18121071/hiding-template-implementation-details-from-doxygen

方法1:Explicitly instantiate the template, and its member definitions

方法2:Copy the implemtation code of the class template into its header file

?

總結(jié):

雖然有2種解決辦法,但是方法一顯然“太笨”,而且“太不靈活”

So, if you plan to create your own class template, then you just don't need to consider enforcing implementation hiding as you do to normal classes, the only way?to hide the implementation of ?a class template is not to provide its header.?

On the other hand, if you decide to design something to be a class template, you must be sure there's nothing need to be hidden for that template, for example:?encryption algorithm or other sensitive stuff.

?

Insight Comment:

The very goal of template is to create a "pattern" so that the compiler can generate classes and functions for a multitude of unrelated types. If you hide this pattern, how do you expect the compiler to be able to generate those classes and functions ?

?

代碼:

?

main.cpp

1 #include "Stack.h" 2 3 #include <iostream> 4 5 using namespace std; 6 7 class Box { 8 public: 9 Box():data(0), ID(num++) { cout << "Box" << ID << " cons" << endl; } 10 Box(const Box &copy): data(copy.data), ID(num++) { cout << "Box" << ID << " copy cons" << endl; } 11 ~Box() { cout << "Box" << ID << " des" << endl; } 12 int data; 13 private: 14 static int num; 15 const int ID; 16 }; 17 18 int Box::num = 1; 19 20 int main() 21 { 22 Box b1,b2,b3; 23 Stack<Box> bstack; 24 bstack.push(b1); 25 bstack.push(b2); 26 bstack.push(b3); 27 return 0; 28 }

?

Stack.h

1 #ifndef STACK_H 2 #define STACK_H 3 4 #include <cstddef> 5 6 template <typename T> 7 class StackImpl; // Stack implementation (hidden), private part 8 // will not be seen by clients 9 10 template <typename T> 11 class Stack 12 { 13 public: 14 Stack(); 15 ~Stack(); 16 /** 17 Inserts a new element at the top of the stack, 18 above its current top element. 19 The content of this new element is 20 initialized to a copy of val. 21 @param val value to which the inserted element is initialized 22 */ 23 void push(const T &val); 24 /** 25 @return a reference to the top element in the stack 26 */ 27 T& top(); 28 /** 29 @return a const reference to the top element in the stack 30 */ 31 const T& top() const; 32 /** 33 Removes the element on top of the stack. 34 This calls the removed element's destructor. 35 */ 36 void pop(); 37 /** 38 @return the number of elements in the stack. 39 */ 40 size_t size(); 41 private: 42 43 StackImpl<T> *impl; // Stack implementation (hidden), private part 44 // will not be seen by clients 45 46 }; 47 48 #endif // STACK_H

?

Stack.cpp

1 #include "Stack.h" 2 3 #include <stdexcept> 4 5 using namespace std; 6 7 template <typename T> 8 class Link { 9 public: 10 11 T data; 12 Link *next; 13 14 Link(const T &_data): data(_data), next(NULL) {} 15 Link(const T &_data, Link *_next): data(_data), next(_next) {} 16 ~Link() { 17 next = NULL; 18 } 19 20 }; 21 22 template <typename T> 23 class StackImpl { 24 public: // even though they're public, but they're not in the header, thus it's safe 25 26 Link<T> *head; 27 28 size_t size; 29 30 StackImpl(): head(NULL) {} 31 ~StackImpl() { 32 Link<T> *ptr = head; 33 while (ptr != NULL) { 34 ptr = head->next; 35 delete head; 36 head = ptr; 37 } 38 size = 0; 39 } 40 }; 41 42 template <typename T> 43 Stack<T>::Stack(): impl(new StackImpl<T>()) {} 44 45 template <typename T> 46 Stack<T>::~Stack() { 47 if (impl != NULL) 48 delete impl; 49 } 50 /** 51 Inserts a new element at the top of the stack, 52 above its current top element. 53 The content of this new element is 54 initialized to a copy of val. 55 @param val value to which the inserted element is initialized 56 */ 57 template <typename T> 58 void Stack<T>::push(const T &val) 59 { 60 impl->head = new Link<T>(val, impl->head); 61 ++(impl->size); 62 } 63 /** 64 @return a reference to the top element in the stack 65 */ 66 template <typename T> 67 T& Stack<T>::top() 68 { 69 if (impl->head == NULL) 70 throw runtime_error("empty stack"); 71 return impl->head->data; 72 73 } 74 /** 75 @return a const reference to the top element in the stack 76 */ 77 template <typename T> 78 const T& Stack<T>::top() const 79 { 80 if (impl->head == NULL) 81 throw runtime_error("empty stack"); 82 return impl->head->data; 83 } 84 /** 85 Removes the element on top of the stack. 86 This calls the removed element's destructor. 87 */ 88 template <typename T> 89 void Stack<T>::pop() 90 { 91 if (impl->head == NULL) 92 throw runtime_error("empty stack"); 93 Link<T> *ptr = impl->head->next; 94 delete impl->head; 95 impl->head = ptr; 96 --(impl->size); 97 } 98 99 /** 100 @return the number of elements in the stack. 101 */ 102 template <typename T> 103 size_t Stack<T>::size() { 104 return impl->size; 105 }

?

轉(zhuǎn)載于:https://www.cnblogs.com/qrlozte/p/4108807.html

總結(jié)

以上是生活随笔為你收集整理的c++ why can't class template hide its implementation in cpp file?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。