第七週 輸入輸出和模板
1.輸入輸出流相關的類
2.用流操縱算子控制輸出格式
3.文件讀寫(一)
4.文件讀寫(二)
5.函數模板
6.類模板
7.類模板與派生、友元和靜態成員變量
7.類模板與派生、友元和靜態成員變量
類模板與派生
類模板與派生包括以下內容:(1)類模板從類模板派生;(2)類模板從模板類派生;(3)類模板從普通類派生;(4)普通類從模板類派生。用的不多。
(1)類模板從類模板派生
template <class T1,class T2>
class A {
T1 v1; T2 v2;
};
template <class T1,class T2>
class B:public A<T2,T1> {
T1 v3; T2 v4;
};
template <class T>
class C:public B<T,T> {
T v5;
};
int main() {
B<int,double> obj1;
C<int> obj2;
return 0;
}
B<int,double> obj1;編譯器實例化出兩個類:
class B<int,double>:public A<double,int>{
int v3; double v4;
};
class A<double, int>{
double v1; int v2;
};
C obj2;編譯器實例化出三個類:
class C:public B<int,int> {
int v5;
};
class B<int,int>:public A<int,int>{
int v3; int v4;
};
class A<int, int>{
int v1; int v2;
};
(2)類模板從模板類派生
template <class T1,class T2>
class A {
T1 v1; T2 v2;
};
template <class T>
class B:public A<int,double> {
T v;
};
int main() {
B<char> obj1; //自動實例化出兩個模板類 :A<int,double> 和 B<char>
return 0;
}
(3)類模板從普通類派生
class A {
int v1;
};
template <class T>
class B:public A { //所有從B實例化得到的類 ,都以A爲基類
T v;
};
int main() {
B<char> obj1;
return 0;
}
(4)普通類從模板類派生
template <class T>
class A {
T v1;
int n;
};
class B:public A<int> {
double v;
};
int main() {
B obj1;
return 0;
}
類模板與友元
類模板與友員函數包括以下內容:(1)函數、類、類的成員函數作爲類模板的友元;(2)函數模板作爲類模板的友元;(3)函數模板作爲類的友元;(4)類模板作爲類模板的友元。
(1)函數、類、類的成員函數作爲類模板的友元
void Func1() { }
class A { };
class B
{
public:
void Func() { }
};
template <class T>
class Tmpl
{
friend void Func1();
friend class A;
friend void B::Func();
};
//任何從Tmp1實例化來的類 ,都有以上三個友元
(2)函數模板作爲類模板的友元
#include <iostream>
#include <string>
using namespace std;
template <class T1,class T2>
class Pair
{
private:
T1 key; //關鍵字
T2 value; //值
public:
Pair(T1 k,T2 v):key(k),value(v) { };
bool operator < ( const Pair<T1,T2> & p) const;
template <class T3,class T4>
friend ostream & operator<< ( ostream & o,const Pair<T3,T4> & p);
};
template<class T1,class T2>
bool Pair<T1,T2>::operator < ( const Pair<T1,T2> & p) const
{
//"小"的意思就是關鍵字小
return key < p.key;
}
template <class T1,class T2>
ostream & operator<< (ostream & o,const Pair<T1,T2> & p)
{
o << "(" << p.key << "," << p.value << ")" ;
return o;
}
int main()
{
Pair<string,int> student("Tom",29);
Pair<int,double> obj(12,3.14);
cout << student << " " << obj;
return 0;
}
輸出:
(Tom,29) (12,3.14)
任意從 template <class T1,class T2> ostream & operator<< (ostream & o,const Pair<T1,T2> & p)生成的函數,都是任意Pair摸板類的友元
(3)函數模板作爲類的友元
#include <iostream>
using namespace std;
class A
{
int v;
public:
A(int n):v(n) { }
template <class T>
friend void Print(const T & p);
};
template <class T>
void Print(const T & p)
{
cout << p.v;
}
int main() {
A a(4);
Print(a);
return 0;
}
輸出:
4
所有從 template void Print(const T & p)生成的函數,都成爲 A 的友元,但是自己寫的函數void Print(int a) { }不會成爲A的友元。
(4)類模板作爲類模板的友元
#include <iostream>
using namespace std;
template <class T>
class B {
T v;
public:
B(T n):v(n) { }
template <class T2>
friend class A;
};
template <class T>
class A {
public:
void Func( ) {
B<int> o(10);
cout << o.v << endl;
}
};
int main()
{
A< double > a;
a.Func ();
return 0;
}
輸出:
10
A< double>類,成了B類的友元。任何從A模版實例化出來的類,都是任何B實例化出來的類的友元
類模板與靜態成員變量
類模板中可以定義靜態成員 ,那麼從該類模板實例化得到的所有類 ,都包含同樣的靜態成員 。
#include <iostream>
using namespace std;
template <class T>
class A
{
private:
static int count;
public:
A() { count ++; }
~A() { count -- ; };
A( A & ) { count ++ ; }
static void PrintCount() { cout << count << endl; }
};
//類的靜態成員都要拿出來單獨聲明
template<> int A<int>::count = 0;
template<> int A<double>::count = 0;
int main()
{
A<int> ia;
A<double> da;
ia.PrintCount();
da.PrintCount();
return 0;
}
輸出:
1
1