c++学习笔记之类模板中的友元声明

类模板中出现3种友元声明,每一种友元声明了与一个或者多个实体的友元关系
(1)普通非模板类或函数的友元声明,将友元关系授予明确指定的类或函数。
(2)类模板或函数模板的友元声明,授予对友元所有实例的访问权。
(3)只授予对类模板或函数模板的特定实例的访问权的友元声明。
1 普通友元

非模板类或非模板函数可以是类模板的友元。

#include <iostream>
using namespace std;

template <class Type> class Bar{
    //普通非模版类
    friend class FooBar;
    //普通非模版函数
    friend void fun();
    private:
        Type data;
    public:
        void setData(Type temp){
            data = temp;
        }
};

class FooBar{
    public:
        //非模版类成员可以访问Bar类实例的任意成员
        void print(){
            Bar<int> bari;
            bari.setData(5);
            cout<<"data:"<<bari.data<<endl;

            Bar<string> bars;
            bars.setData("No");
            cout<<"data:"<<bars.data<<endl;
        }
};
//非模版函数可以访问Bar类实例的任意成员
void fun(){
    Bar<int> bari;
    bari.setData(4);
    cout<<"data:"<<bari.data<<endl;

    Bar<string> bars;
    bars.setData("Yes");
    cout<<"data:"<<bars.data<<endl;
}

int main(){
    fun();

    FooBar fooBar;
    fooBar.print();

    return 0;
}

以上代码说明FooBar的成员和fun函数可以访问Bar类的任意实例的private成员和protected成员

2 一般模版友元关系
友元可以是类模版或者函数模版

#include <iostream>
using namespace std;

template <class Type> class Bar{
    //模版类
    template <class T> friend class FooBar;
    //模版函数
    template <class T> friend void fun(const Bar<T>&);
    private:
        Type data;
    public:
        void setData(Type temp){
            data = temp;
        }
};

template <class T> class FooBar{
    public:
        //模版类成员可以访问Bar类实例的任意成员
        template <class U> void print(Bar<U> &bar){
            cout<<"模版类:"<<bar.data<<endl;
        }
};

//模版函数可以访问Bar类实例的任意成员
template <class T> void fun(const Bar<T> &bar){
    cout<<"模版函数:"<<bar.data<<endl;
}

int main(){
    Bar<int> bari;
    bari.setData(4);

    Bar<string> bars;
    bars.setData("Yes");

    fun(bari);
    fun(bars);

    FooBar<int> fooBari;
    FooBar<string> fooBars;

    fooBari.print(bari);
    fooBars.print(bars);
    return 0;
}

一般模板友元关系:FooBar的任意实例都可以访问Bar的任意实例的私有成员。fun函数相同。

3 特定的模版友元
除了将一个模版的实例设为友元,类也可以只授予对特定实例的访问权。

#include <iostream>
using namespace std;

//模版声明
template <class T> class Bar;
template <class T> class FooBar;
template <class T> void fun(const Bar<T>&);

template <class Type> class Bar{
    //模版类特定实例
    friend class FooBar<int>;
    //模版函数特定实例
    friend void fun<int>(const Bar<int>&);
    private:
        Type data;
    public:
        void setData(Type temp){
            data = temp;
        }
};

template <class T> class FooBar{
    public:
        template <class U> void print(Bar<U> &bar){
            cout<<"模版类:"<<bar.data<<endl;
        }
};

template <class T> void fun(const Bar<T> &bar){
    cout<<"模版函数:"<<bar.data<<endl;
}

int main(){
    Bar<int> bari;
    bari.setData(4);

    Bar<string> bars;
    bars.setData("Yes");

    fun(bari);
    //fun(bars);   error:Type data is private

    FooBar<int> fooBari;
    FooBar<string> fooBars;

    fooBari.print(bari);
    //fooBars.print(bars); error:Type data is private
    return 0;
}
时间: 2024-09-16 13:27:34

c++学习笔记之类模板中的友元声明的相关文章

Symfony2学习笔记之模板用法详解_php实例

本文实例讲述了Symfony2学习笔记之模板用法.分享给大家供大家参考,具体如下: 我们知道,controller负责处理每一个进入Symfony2应用程序的请求.实际上,controller把大部分的繁重工作都委托给了其它地方,以使代码能够被测试和重用.当一个controller需要生成HTML,CSS或者其他内容时,它把这些工作给了一个模板化引擎. 模板: 一个模板仅仅是一个文本文件,它能生成任意的文本格式(HTML,XML,CSV,LaTex...).最著名的模板类型就是PHP模板了,可以

目标跟踪学习笔记_1(opencv中meanshift和camshift例子的应用)

在这一节中,主要讲目标跟踪的一个重要的算法Camshift,因为它是连续自使用的meanShift,所以这2个函数opencv中都有,且都很重要.为了让大家先达到一个感性认识.这节主要是看懂和运行opencv中给的sample并稍加修改.      Camshift函数的原型为:RotatedRect CamShift(InputArray probImage, Rect& window, TermCriteria criteria).      其中probImage为输入图像直方图的反向投影

jQuery学习笔记[1] jQuery中的DOM操作_jquery

DOM分为3个方面,即DOM Core,HTML-DOM,CSS-DOM. 1,DOM Core并不专属于JavaScript,任何一种支持DOM的程序设计语言都可以使用它. JavaScript中的getElementById(),getElementsByTagName()...等方法. 例如:使用DOM Core来获取表单对象的方法: document.getElementsByTagName("form"); 2,HTML-DOM. 在使用JavaScript和DOM为HTML

JSP学习笔记(五)-----JSP中使用JavaBean

js|笔记 1. 该实例主要告诉我们怎么样在JSP代码中调用JavaBean构件2. 使用JavaBean的优点是简化了JSP代码,界面代码和逻辑代码互相分离,便于程序员查看和调试3. 该实例需要五个文件:login.jsp,test.jsp, userbean.class4. 首先看一下login.jsp <html><center><form method=post action="http://127.0.0.1:8000/test.jsp">

C#.NET学习笔记5 C#中的条件编译_C#教程

条件编译是C#比Java多出的东西,但我跟前辈请教后,他们都说条件编译在实际的项目开发中不怎么使用.鉴于是新内容,我还是做做笔记,理解一下好了. 条件编译属于编译预处理的范畴,它能让我们通过条件编译的机制,将部分代码包括进来或者排除出去,其作用与if-else类似.条件编译指令有以下四种? #if? #elif? #else? #endif 条件编译指令有以下四种 #if #elif    #else #endif 下面我们通一些例子来说明它们的用法 复制代码 代码如下: #define Deb

&lt;极客学院&gt;视频教程学习笔记-iOS中CALayer的使用

<1>CALayer简介 1.CALayer一般作为UIView的容器而使用. 2.CALayer是一个管理者图片载体(image-based content)的层结构 3.直接修改单独创建出的CALayer的属性可以触发隐式动画 4.UIView中的CALayer动画必须显式触发才能生效 开篇代码练习: 1 #import "ViewController.h" 2 3 @interface ViewController () 4 //2单独创建一个layer 5 @pro

CSS学习笔记Padding 属性中参数的定义与使用_经验交流

一直都对CSS中Padding 属性中参数个数的定义颇为困惑,例如: body { padding: 32px;} body { padding: 32px 24px; } body { padding: 32px 24px 18px; } body { padding: 32px 24px 18px 12px; } 今天baidu查看了CSS的标准文档,其中是这样规定的: 如果只提供一个,将用于全部的四条边: 如果提供两个,第一个用于上-下,第二个用于左-右: 如果提供三个,第一个用于上,第二

JavaScript 学习笔记之基础中的基础_基础知识

概要:javascript的组成. 各个组成部分的作用 . 一.javascript的组成   javascript  ECMAScript(核心) DOM(文档对象模型) BOM(浏览器对象模型) 1.1ECMAScript ECMAScript是通过ECMA-262标准化的脚本语言,ECMA-262规定语言的:语法.类型.语句.关键字.保留字.操作符.对象 1.2 DOM DOM把整个页面映射为一个多层节点结构,HTML或者XML等页面中的每个组成部分都是某种类型的节点,这些节点又包含不同类

jQuery学习笔记之jQuery中的$_jquery

在jQuery中,最常用的莫过于使用美元符号$,它提供了各种各样的丰富功能.包括选择页面中一个或者一类元素.作为功能函数的前缀.windows.onload的完善,创建DOM节点等.本文介绍jQuery的用法.作为基础 1.选择器 在css中,选择器的作用是选择页面的某一类(类别选择器)元素或者某个(id选择器).而jQuery中的"$"作为选择器,同样是选择某类或者某个元素,只不过jQuery提供了更全面的选择方式.而且为用户处理了浏览器兼容问题. 例如在在css<h2>