第十九天(C++代码重用IV)
来源:互联网 发布:单片机初始化程序 编辑:程序博客网 时间:2024/05/16 13:43
昨晚写完已断网,故而今早上传。另,可能是这章内容太多,可能是我太过啰嗦,这章居然被我分了五部分。今天或者明天,还会有part V
2012-3-22(Reusing Code in C++part IV)
13. Class Templates
Inheritance and containment aren't always the solution when you want to reuse code. Instead, using class templates are more commonly. Like function templates, templates instructions to the C++ compiler about how to generate class definitions. Unlike function templates, class templates provide parameterized types---that is, the capable of passing type name as an argument to a recipe for building a class.
I. Syntax
A typical class model would like this:
class exam{private: int member;public: int function1();exam function2();};Then, if we want to declare a class template,modify it as follows:
template <class Type>//or <typename Type>class exam{private: Type member;public: Type function1();exam function2();}
Also,you need to make a little change when defining member functions:
template <class Type>Type exam<Type>::function1() {/*function body*/}template <class Type>exam<Type> exam<Type>::function2() {/*function body*/}We need to change the class qualifier from exam:: to exam<Type>::. But we can use exam:: or exam instead of exam<Type>:: or exam<Type> inside the template declaration and template function definitions.
II. Caution
Again, class templates are not class and member function definitions. Rather, they tell the compiler to how to generate a specific class. A particular actualization of a template is called aninstantiation or a specialization.Because, the templates aren't functions, placing the template member functions in a separate implementation file won't work, unless you use a compiler that has implemented the new export keyword.
But most of compilers,including Microsoft Visual Studio 2010 Express that I am using are not yet support this keyword (warning in VS2010):
'export' keyword isnot yet supported,but reserved for future use
Looking for the reason in the Internet: too complex to implement.
It's strange that when I try to separate declaration and implementation, my compiler reports no problem.I don't know why. For compatibility, we are supposed to place all the template information in a herder file.
14. Design a Simple Array Template
Templates are frequently used for container classes because the idea of type parameters matches well with the need to apply a common storage plan to a variety of types. A typical array template has the following functions (a portion):
- size (); //return the number of elements
- operator [](); //set and get the value of element
We need to specify an array size when creating an array. Two techniques to reach this goal: one is use a dynamic array within the class and a constructor argument to provide the number of elements. Another approach is to use a template argument to provide the size for a regular an ordinary array.
I. Dynamic Array
#ifndef _DARRAY_#define _DARRAY_template <typename T>class DArray{private: int array_size; T* elems;public: DArray (int size = 10); //contructor DArray (const DArray& da); //copy contructor ~DArray(){delete[] elems;} //destructor int size() {return array_size;} const T& operator [](int i) const; //prepare for const objects T& operator [](int i); //get & set certain element DArray& operator =(const DArray& da); //assignment operator};template <typename T>DArray<T>::DArray(int size = 10): array_size(size){ elems = new T[size];}template <typename T>DArray<T>::DArray(const DArray& da){ array_size = da.array_size; elems = new T[array_size]; for(int i = 0; i< array_size; i++) elems[i] = da.elems[i];}template <typename T>const T& DArray<T>::operator [](int i) const{ return elems[i];}template <typename T>T& DArray<T>::operator [](int i){ return elems[i];}template <typename T>DArray<T>& DArray<T>::operator =(const DArray& da){ if(this == &da) return *this; delete[] elems; array_size = da.array_size; elems = new T[array_size]; for(int i = 0; i< array_size; i++) elems[i] = da.elems[i]; return *this;}#endifUsing dynamic array internally, so the class needs a destructor, copy constructor and an assignment operator.
II. Non-Type Arguments
#ifndef _NARRAY_#define _NARRAY_template <typename T, int n>class NArray{private: T elems[n];public:NArray() {} //default constructor//create an object that all elements are eexplicit NArray(const T& e); int size() const { return n; };const T& operator [](int i) const;T& operator [](int i);};template <typename T, int n>NArray<T,n>::NArray(const T& e){ for(int i = 0; i< n; i++) elems[i] = e;}template <typename T, int n>const T& NArray<T,n>::operator[](int i)const{ return elems[i];}template <typename T, int n>T& NArray<T,n>::operator[](int i){ return elems[i];}#endiftemplateheadingtemplate <typename T, int n>, whose second kind of parameter specifies a particular type instead of acing as a generic for a type, is called anon-type(or expression) argument.
Non-type arguments have some restrictions. Anon-type can be an integral type, an enumeration type, a reference or a pointer. Also, the templates code can't modify the value of the argument or take its address. In other word, expression like n++ or &n would not be allowed inside the class templates. And when instantiate a template, the value used for the expression argument should be a constant expression.
III. Testing
Two techniques have the same name of interface, so I can use a similar test program.
#include <iostream>//#include "NArray.h"#include "DArray.h"using namespace std;int main(){ //NArray<double,7> da(5.0); DArray<double> da(7); cout << da.size() << endl; for(int i = 0; i< 6; i++) da[i] = double(i * 2); //const NArray<double,7> nda = da; const DArray<double> nda = da; for(int i = 0; i< nda.size(); i++) cout << nda[i] << " "; cout << endl; for(int i = 0; i< da.size(); i++) cout << da[i] << " ";}
The comment portion is prepare for non-type argument.
VI. Comparison
① Argument approach has less execution time. Constructor approach uses heap memory managed bynew and delete, while expression argument uses the memory stack maintained for automatic variables.
② Argument approach costs more resource. For example
NArray<int,7> one;
NArray<int,8> two;
generate two separate class declarations. But
DArray<int> one(7);
DArray<int> two(8);
generate just one separate declaration.
③ Constructor approach is more versatile. Because its array size is stored as a class member. So that, for example, we can assignment from an array of one size to an array of another size or to define a function to resize the array.
- 第十九天(C++代码重用IV)
- C/C++第十九天
- c/c++第十九天
- 第十七天(C++代码重用II)
- 第十八天(C++代码重用III)
- 第十九天-Java_IO(流)
- C++Primer学习笔记(代码重用)
- 第十九天
- 我的android(第十九天)
- c++primer第十四章c++代码重用(二)
- 世界杯第十九天
- 第十九天:听课笔记
- 第十九天:总结
- 第十九天总结0415
- 星海第十九天
- 第十九天博客
- 第十九天:IO流
- php实战第十九天
- vi 多行复制
- 使用常对象——为共用数据加装一个名为const的玻璃罩
- 那年,一步一步学linux c ---华为面试题之Variable
- _T() 函数
- Failed to create the Java Virtual Machine
- 第十九天(C++代码重用IV)
- 二分排序与二分查找
- 实验3_Java类的继承和接口的定义和使用
- 哈希表
- VC++ 之 RichEdit 常见使用技
- 深入研究java.lang.ThreadLocal类
- 语音虚拟助理将引领下一代互联网人机交互
- 随机文本生成与马尔科夫链
- html+qjquery 实现变色