標籤:產生 構造 虛擬 地址 釋放 一個 ace let sof
需求:類比數組類,只不過數群組類型不再是整型、浮點型等,也可以是類。
1、建立模板類
標頭檔
#ifndef MYVECTOR_H#define MYVECTOR_H#include <iostream>#include"Teacher.h"using namespace std;template <typename T>class myVector{public: myVector(); void init(int size=0); //建構函式 myVector(const myVector &obj); //拷貝建構函式 ~myVector(); //解構函式 const int getLen() const; const T* getSpace() const {return m_space;} T& operator [](int index); myVector<T> &operator =(const myVector<T> &obj);private: T *m_space; int m_len;};#endif // MYVECTOR_H
資源檔
#include "myvector.h"#include"Teacher.h"template<typename T>myVector<T>::myVector(){ m_space = NULL; m_len = 0;}template<typename T>void myVector<T>::init(int size){ m_space=new T[size]; this->m_len=size;}template<typename T>myVector<T>::myVector(const myVector &obj) //拷貝建構函式{ m_len=obj.m_len; cout<<m_len<<endl; m_space=new T[m_len]; for (int i = 0; i < m_len; ++i) { m_space[i]=obj.m_space[i]; }}template<typename T>myVector<T>::~myVector() //解構函式{ cout<<"destory....."<<endl; if(m_space != NULL){ delete [] m_space; m_space=NULL; m_len=0; }}template<typename T>const int myVector<T>::getLen() const{ return m_len;}template<typename T>T& myVector<T>::operator [](int index){ return m_space[index];}template<typename T>myVector<T> & myVector<T>::operator= (const myVector<T> &obj){ //先釋放舊的記憶體 if(m_space != NULL){ cout<<"not null"<<endl; delete[] m_space; m_space=NULL; m_len=0; } //根據參數分配記憶體 int length = obj.getLen(); m_space=new T[length]; this->m_len=length; for (int i = 0; i < m_len; ++i) { m_space[i]=obj.getSpace()[i]; } return *this;}
2、實驗類
標頭檔
#ifndef TEACHER_H#define TEACHER_H#include<iostream>using namespace std;class Teacher{public: Teacher(); Teacher(char *name,int age); Teacher(const Teacher &teacher); ~Teacher(); void printTeacher(); friend ostream &operator <<(ostream &out,Teacher &teacher); Teacher &operator =(const Teacher &teacher);private: int age; char *name;};#endif // TEACHER_H
資源檔
#include "Teacher.h"#include<iostream>#include<string.h>using namespace std;Teacher::Teacher(){ age=0; name=new char[1]; strcpy(name," ");}Teacher::Teacher(char *name, int age){ this->name=new char[strlen(name)]; strcpy(this->name,name); this->age=age;}Teacher::Teacher(const Teacher &teacher){ this->name=new char[strlen(teacher.name)]; strcpy(this->name,teacher.name); this->age=age;}Teacher::~Teacher(){ if(this->name!=NULL){ delete[] this->name; this->name=NULL; age==0; }}void Teacher::printTeacher(){ cout<<"Teacher( name: "<<this->name<<" age: "<<this->age<<" )"<<endl;}ostream &operator <<(ostream &out,Teacher &teacher){ out<<"Teacher( name: "<<teacher.name<<" age: "<<teacher.age<<" )"<<endl; return out;}Teacher & Teacher::operator =(const Teacher &teacher){ if (this->name != NULL) { delete[] this->name; this->name=NULL; } this->name=new char[strlen(teacher.name)]; strcpy(this->name,teacher.name); this->age=teacher.age; return *this;}
3、測試函數
主函數
#include "myvector.cpp"#include"Teacher.h"int main(){ myVector<int> myv; myv.init(10); for (int i = 0; i < myv.getLen(); ++i) { myv[i] = i+1; cout<<myv[i]<<" "; } cout<<endl; myVector<int> myv2=myv; for (int i = 0; i < myv2.getLen(); ++i) { cout<<myv2[i]<<" "; } cout<<endl; myVector<int> myv3; myv3=myv; for (int i = 0; i < myv3.getLen(); ++i) { cout<<myv3[i]<<" "; } Teacher t1("ggg",22),t2("qqq",23),t3("xxx",24); myVector<Teacher> t; t.init(3); t[0]=t1; t[1]=t2; t[2]=t3; cout<<endl; for (int i = 0; i < 3; ++i) { cout<<t[i]; } return 0;}
注意事項:
在主函數中加入了
#include "myvector.cpp"
問題的根源在於編譯器對於模板(template)的編譯處理過程中,
大致是這樣的(果真如此嗎?):
1、模板myVector在編譯(compile)期間並未產生具體二進位代碼,
在main函數中也沒有嵌入這個函數的代碼,可能只是包含了一句
call testFunc之類的(稍後詳述)
2、編譯階段,在main函數中發現了myVector的引用,但是main.obj中沒有相關的
可執行代碼(編譯器認為該函數在別處定義,這就是為什麼需要連結也就是
LINK了,在main中雖然引用到myVector但是只提供了一個call虛擬位址而沒有
實際的執行代碼)
3、連結階段,將各個模組(編譯期間產生的很多*.obj檔案)組織起來
形象的說就是,在LINK的時候把testFunc“嵌入”進來,就像是一個子過程,
在main中從調用處jump到這裡即可,執行完畢再跳出子模組,從“中斷點”
繼續執行後續語句)
4、模板在編譯期間是不產生具體代碼的。
C++模板的應用