1. 程式人生 > >友元與模板類

友元與模板類

友元成員函式模板:

#include <iostream>

using namespace std;

template<class T> class A;    //當用到友元成員函式時,需注意友元宣告與友元定義之間的互相依賴。這是類A的宣告
template<class T>
class B
{
public:
	void set_show(int x, A<T> &a);             //該函式是類A的友元函式
};
template<class T> //A的這個T決定了對於B的T型別友元,並且只友元A<T>型別
class A
{
public:
	friend void B<T>::set_show(int x, A<T> &a);   //該函式是友元成員函式的宣告
private:
	int data;
	void show() { cout << data << endl; }
};
template<class T>
void B<T>::set_show(int x, A<T> &a)       //只有在定義類A後才能定義該函式,畢竟,它被設為友元是為了訪問類A的成員
{
	a.data = x;
	cout << a.data << endl;
}

int main(void)
{
	class A<int> a;//B的set_show只能訪問A<int>型別,只對這個型別友元
	class B<int> b;//B必須是int才能訪問a的成員,否則不行

	b.set_show(1, a);
	getchar();
	return 0;
}

類模板(class template)友元(friend)和普通類的友元, 有很多區別,

主要原因是類模板包含模板引數(template parameter), 就會導致友元和類模板有很多匹配形式;

主要包含六種形式:

1. 類 - 友元(friend): "模板引數是當前類"的類模板;

2. 類 - 友元: "模板引數任意"的模板類;

3. 模板類 - 友元: "模板引數相同"的模板類;

4. 模板類 - 友元: "模板引數任意"的模板類

5. 模板類 - 友元: 類;

6. 模板類 - 友元: 當前模板引數(類); (C++11)

具體使用參見程式碼及註釋,

程式碼如下:

/*
 * cppprimer.cpp
 *
 *  Created on: 2013.11.24
 *      Author: Caroline
 */

/*eclipse cdt, gcc 4.8.1*/

#include <iostream>
#include <string>

template <typename T> class Pal; //pal朋友

class C {
	friend class Pal<C>; //"以類C例項化"的Pal類, 為C的友元
	template <typename T> friend class Pal2; //Pal2類的所有例項化, 都為C的友元
private:
	void print() { std::cout << "class C" << std::endl; }
};

template <typename T>
class C2 {
	friend class Pal<T>; //"與C2類相同例項化"的Pal類, 為C2的友元
	//Pal2類的所有例項化, 都為C2的友元, 注意模板引數(X)不能相同
	template <typename X> friend class Pal2;
	friend class Pal3; //普通友元
	friend T; //C++11 模板型別引數友元
private:
	void print() { std::cout << "class C2" << std::endl; }
};

template <typename T>
class Pal {
	C myC;
	C2<T> myC2; //必須為T
	//C2<double> myC2; //例項化不同, 無法使用
public:
	void printC() {
		std::cout << "this is class Pal : ";
		myC.print();
	}
	void printC2() {
		std::cout << "this is class Pal : ";
		myC2.print();
	}
};

template <typename T>
class Pal2 {
	C myC;
	C2<double> myC2;
public:
	void printC() {
		std::cout << "this is class Pal2 : ";
		myC.print();
	}
	void printC2() {
		std::cout << "this is class Pal2 : ";
		myC2.print();
	}
};

class Pal3 {
	C2<double> myC2;
public:
	void printC2() {
		std::cout << "this is class Pal3 : ";
		myC2.print();
	}
};

class Pal4 {
	C2<Pal4> myC2; //注意Pal4是C2類的模板引數
public:
	void printC2() {
		std::cout << "this is class Pal4 : ";
		myC2.print();
	}
};

int main (void) {

	std::cout << "Hello Mystra!" << std::endl;

	Pal<C> pc; //Pal類必須例項化為C
	pc.printC(); //可以使用
	//Pal<int> pci;
	//pci.print(); //報錯, 訪問了私有成員

	Pal2<int> pi2; //Pal2類可以隨意例項化
	pi2.printC();

	Pal<int> pi; //有相同的示例化, 在類宣告C2<T>
	pi.printC2();

	pi2.printC2(); //注意, Pal2類被例項化為<int>, 內部C2類被例項化為<double>;

	Pal3 p3;
	p3.printC2();

	Pal4 p4;
	p4.printC2();

	return 0;
}


相關推薦

模板

友元成員函式模板:#include <iostream> using namespace std; template<class T> class A; //當用到友元成員函式時,需注意友元宣告與友元定義之間的互相依賴。這是類A的宣告 tem

C++學習之路(47)---C++模板模板深入詳解

1、在c++的Template中很多地方都用到了typename與class這兩個關鍵字,而且有時候二者可以替換,那麼是不是這兩個關鍵字完全一樣呢? 事實上class用於定義類,在模板引入c++後,最初定義模板的方法為:template<class T>,這裡cl

C++ Template模板函式模板

函式模板擴充套件了函式過載並簡化函式的過載: 利用函式過載可以讓多個函式共享一個函式名,只要所過載的函式的引數型別必須有所不同。 但是,由於引數的型別不一樣,雖然這些函式所完成的功能完全一樣,也必須為每一個過載函式編寫程式碼。 類模板實際上是函式模板的推廣, 它是一種不確定類的某些資料成員的

c++模板學習-模板模板詳解-2

c++模板學習 https://blog.csdn.net/u010029439/article/details/84977348   資料來源: https://www.cnblogs.com/cxq0017/p/6076856.html   在C++的

【C++】靜態成員

友元 C++中,類外的成員不能訪問類內的私有和保護型別成員。而友元函式可以不受訪問限制訪問類的任何成員。友元函式雖然可以在類內進行宣告,但是友元函式不是成員函式,因此沒有this指標。 舉例說明: class Clock { public: Clo

C++學習筆記46——繼承

1,總的原則 繼承層次中關於友元的總原則就是:友元關係不能繼承。可以概述如下: 老爸的朋友不一定是我的朋友;朋友的兒子不一定還是朋友;由以上兩條不難推出:老爸的朋友的兒子不一定還是朋友 但具體實施

通過函式修改的私有屬性

#include<iostream>//21 using namespace std; //友元函式 class A { public: friend void modifyA(A *pA, int _a); A(int _a, int _b) { th

C++ 模板模板詳解

轉自:https://www.cnblogs.com/cxq0017/p/6076856.html在C++的Template中很多地方都用到了typename與class這兩個關鍵字,有時候這兩者可以替換,那麼這兩個關鍵字是否完全一樣呢?  事實上class用於定義類,在模板

模板函式模板

前言:通常我們想要比較不同資料型別的時候不得不定義兩種不同的函式來表示區分,為了能精簡程式碼和避免強型別的嚴格性和靈活性的衝突,我們就需要用到模板去改善這種情況。 一、函式模板 //函式模版的隱式例項化 #include <iostream> usin

C++函式訪問的私有成員

#include <iostream>#include<cstring>using namespace std ;class Student{private:string  name;int age;int sore;public:Student(string name,int age

區分類模板模板的概念

在C++的Template中很多地方都用到了typename與class這兩個關鍵字,有時候這兩者可以替換,那麼這兩個關鍵字是否完全一樣呢?  事實上class用於定義類,在模板引入c++後,最初定義模板的方法為:template<class T>,這裡class

C/C++ 指標陣列陣列指標、函式指標指標函式、模板函式函式模板模板模板區別

函式模板與模板函式、模板類與類模板區別: 在C++中有好幾個這樣的術語很重要: 函式指標——指標函式陣列指標——指標陣列類模板——模板類函式模板——模板函式  1.函式指標——指標函式     函式指標的重點是指標。表示的是一個指標,它指向的是一個函式,例子:   int

不用,訪問的私有成員變數的方法

   雖然沒有現實意義,但對理解C++的物件模型是很有幫助的。    前幾天,在論壇裡看到一個帖子,內容是:     (原帖見:http://community.csdn.net/Expert/topic/5014/5014384.xml?temp=.3018152)    

C++之模板函式模板

C++中的模板是為了適應不同資料型別的呼叫。關鍵詞有template class typename template <typename T>T  max(T a, T b){  return (a>b) ? a:b;}class和typename在模板中意

C++異常

C++ Primer Plus讀書筆記 友元 友元不僅可以是一個函式,並且可以是類,友元類的所有方法都可以訪問原始類的私有成員和保護成員。同時,可以做更加細緻的限定:只將特定的成員函式指定為一

c++ 函式,模板函式

友元函式. 類的友元函式是定義在類外部,但有權訪問類的所有私有(private)成員和保護(protected)成員。儘管友元函式的原型有在類的定義中出現過,但是友元函式並不是成員函式。 友元可以是一個函式,該函式被稱為友元函式;友元也可以是一個類,該類被稱

js的原型模板

原型對象 概念 臨時變量 信息 nbsp 所有 構造對象 bsp 復用 原型處於復用(原型)鏈上; 模版類型屬於構造概念; 對象復用原型的數據和函數; 對象由模版類型+原型構造而成; 模版類型屬於構造對象的臨時變量,包含了對象空間的所有信息; 原型包含

c/c++ 模板STL小例子系列<二> 模板函數

vat stream col ons cout include ios ring 沒有 c/c++ 模板與STL小例子系列<二> 模板類與友元函數 比如某個類是個模板類D,有個需求是需要重載D的operator<<函數,這時就需要用到友元。 實現這樣

關於模板函式的宣告定義

//Widget.h #ifndef _WIDGET_H_ #define _WIDGET_H_ #include <iostream> using namespace std; template<class T> class Widget {

模板函式

模板的友元可以分為三類: 非模板友元約束模板友元,即友元的型別取決於類被例項化時的型別非約束模板友元,即友元的所有具體化都是類的每一個具體化的友元 1. 模板類的非模板友元,即該友元函式不存在模板,但是該友元函式聲明於一個模板類中。 圖1 如果沒有需要模板類引數,這與