中國大學MOOC程序設計與算法(三):C++ 面向對象程序設計 第七週 輸入輸出和模板 筆記 之 類模板與派生、友元和靜態成員變量

第七週 輸入輸出和模板
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
發佈了53 篇原創文章 · 獲贊 4 · 訪問量 1991
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章