友元概念就不罗嗦了,使用也简单,就两种形式:
1.友元函数:friend ret-type classname::funname(....);
2.友元类:friend class classname;
唯一要注意的就是不管是友元函数还是友元类,定义友元关系前必须先声明
友元类其实还是有些故事要说的,一旦类继承起来友元关系还是有些小复杂的,下面简单说明:
C中声明A是其友元类,那么最基本的就是A可以使用C中的private方法或者对象。
图中可见,A是B的基类,C是D的基类。ABCD中就有如下关系:
1.B新增的方法不能访问C的私有成员
2.B从A继承而来的方法可以访问C的私有成员
3.A只能访问D中从C中继承而来的私有成员,D中新增的私有成员不能访问!
总结起来:
(1)友元关系不可以继承,但对已有的方法来说访问权限不改变。
(2)如果改写基类的方法则访问权限改变
(3)友元关系不具有传递性
若类B是类A的友元,类C是B的友元,类C不一定是类A的友元
下面一个例子说明了友元模板类的定义。
#include <iostream>
using namespace std;
//using std::cout;
template <typename T>
class Node
{
template <typename T> friend class ListNode;
//友元模板类的声明,这种写法friend class ListNode<T>;有的教材提到,没编译通过
private:
T data;
Node<T> *next;//模板函数变量的定义一定不要玩了参数列表
};
template <typename T>
class ListNode
{
private:
Node<T> *first;
public:
ListNode(){ first = 0; }
~ListNode();
ListNode & Insert(int k,T &x);
ListNode & Delete(T &x);
bool IsEmpty()const;
int Length()const;
void display()const;
};
template <typename T>
ListNode<T>::~ListNode()
{
Node<T> *curr = first->next;
Node<T> *prev = first;
while(curr)
{
delete prev;
prev = curr;
curr = curr->next;
}
}
template<typename T>
bool ListNode<T>::IsEmpty()const
{
return first == 0
}
template <typename T>
ListNode<T> & ListNode<T>::Insert(int k,T &x)
{
Node<T> *curr = first;
Node<T> *temp;
int index =0;
temp = first;
temp = new Node<T>;
temp->data = x;
temp->next =0;
if(k<0 || k>Length())
{
cout<<"the input location is illegal"<<endl;
return *this;
//exit(1);
}
if(k==0 && first==0)
{
temp->next = first;
first = temp;
}
else
{
for(index=0;index<k;index++)
curr = curr->next;
temp->next = curr->next;
curr->next = temp;
}
return *this;
}
template <typename T>
int ListNode<T>::Length()const
{
int index = 0;
Node<T> *curr = first;
while(curr)
{
index++;
curr = curr->next;
}
return index;
}
template <typename T>
ListNode<T> & ListNode<T>::Delete(T &x)
{
Node<T> *curr = first->next;
Node<T> *prev = first;
while(curr)
{
if(first->data == x)
{
first = first->next;
delete prev;
}
else
{
if(curr->data == x)
{
prev->next = curr->next;
delete curr;
}
}
prev = curr;
curr = curr->next;
}
return *this;
}
template <typename T>
void ListNode<T>::display()const
{
Node<T> *curr = first;
while(curr)
{
cout<<curr->data<<" ";
curr = curr->next;
}
}
分享到:
相关推荐
1) 用List模板定义一个List类型的模板类对象int_listB,从键盘读入m个整数,调用Push_back函数将这m个整数依次插入到该链表中;(4分) 2) 用List模板定义一个List类型的模板类对象int_listC,从键盘读入n个整数,...
实现了一个比较通用的矩阵模板,能够完成+ - * / 求模,求逆, 点乘等多种操作。随便弄点小分,要是没分的直接M我吧。
3.(选做)定义类X、Y、Z,函数h(X *),满足:类X有私有成员i,Y的成员函数g(X *)是X的友元函数,实现对X的成员i加1,类Z是类X的友元类,其成员函数f(X *)实现对X的成员i加5,函数h(X *)是X的友元函数,...
【C++ 语言】面向对象 ( 类定义 | 限制头文件引用次数 | 构造方法 | 析构方法 ) : https://hanshuliang.blog.csdn.net/article/details/99609557 【C++ 语言】面向对象 ( 成员函数 | 常量函数 | 友元函数 | 友元类 ...
3.11 友元函数和友元类 58 3.11.3 友元类 61 3.12 C++字符串 62 四、C++面向对象:继承与派生 75 4.1 继承与派生概念介绍 75 4.2 继承的语法介绍 75 4.3 继承方式介绍(继承的权限) 76 4.4 继承时变量与函数名字遮蔽...
12.1.3 关于类定义的更多内容 372 12.1.4 类声明与类定义 374 12.1.5 类对象 375 12.2 隐含的this指针 376 12.3 类作用域 380 类作用域中的名字查找 382 12.4 构造函数 385 12.4.1 构造函数初始化式 387 12.4.2 默认...
2.12章 类定义(一) 3.12章 类定义(二) 4.12章 类定义(三) 5.12章 隐含的this指针 6.12章 类作用域 7.12章 构造函数 8.12章 友元 9.12章 static类成员 10.13章 复制构造函数和赋值操作符 11.13章 ...
鸡啄米:C++编程入门系列之十六(类与对象:类模板) 鸡啄米:C++编程入门系列之十七(类与对象:UML简介) 第五部分:C++程序设计必知 鸡啄米:C++编程入门系列之十八(C++程序设计必知:作用域和可见 性) ...
15.2 使用CList模板类 15.2.1 绘制曲线 15.2.2 定义CCurve类 15.2.3 实现CCurve类 15.2.4 练习使用CCurve类 15.3 创建文档 15.4 改进视图 15.4.1 更新多个视图 15.4.2 滚动视图 15.4.3 使用MM_LOENGLISH映射模式 ...
15.2 使用CList模板类 15.2.1 绘制曲线 15.2.2 定义CCurve类 15.2.3 实现CCurve类 15.2.4 练习使用CCurve类 15.3 创建文档 15.4 改进视图 15.4.1 更新多个视图 15.4.2 滚动视图 15.4.3 使用MM_LOENGLISH映射模式 ...
65. 类模板继承时的语法与普通的类继承有什么不同? 13 66. 什么是打开文件?什么是关闭文件?为什么需要打开和关闭文件? 14 67. 为什么要检查文件打开是否成功?如何检查? 14 68. ASCII文件和二进制文件有什么...
15.2 使用CList模板类 15.2.1 绘制曲线 15.2.2 定义CCurve类 15.2.3 实现CCurve类 15.2.4 练习使用CCurve类 15.3 创建文档 15.4 改进视图 15.4.1 更新多个视图 15.4.2 滚动视图 15.4.3 使用MM_LOENGLISH映射模式 ...
第11章 类中的友元函数、重载操作符和数组 第12章 独立编译和命名空间 第13章 指针和链表 第14章 递归 第15章 继承 第16章 异常处理 第17章 模板 第18章 标准模板库 附录1 C++关键字 附录2 操作符的优先级 附录3 ...
7.1.3 定义类相关的非成员函数 234 7.1.4 构造函数 235 7.1.5 拷贝、赋值和析构 239 7.2 访问控制与封装 240 7.2.1 友元 241 7.3 类的其他特性 243 7.3.1 类成员再探 243 7.3.2 返回*this的成员函数...
7.1.3 定义类相关的非成员函数 234 7.1.4 构造函数 235 7.1.5 拷贝、赋值和析构 239 7.2 访问控制与封装 240 7.2.1 友元 241 7.3 类的其他特性 243 7.3.1 类成员再探 243 7.3.2 返回*this的成员函数...
8、类定义的内容允许被其对象无限制地存取的是( )。 A.private 部分 B. protected 部分 C.public 部分 D.以上都不对 9、关于常数据成员的说法,不正确的是( )。 A.常数据成员的定义形式与一般常变量的,只...
16.2.2 C++中的模板类vector和 basic_string 478 16.3 模板和继承 478 第17章 链式数据结构 487 17.1 节点和链表 487 17.1.1 节点 487 17.1.2 链表 491 17.1.3 向链表头插入一个节点 492 17.1.4 向链表中...
继承不是类之间的一种关系 C++语言仅支持单一继承 继承会增加程序的冗余性 继承是面向对象方法中一个很重要的特性 ~D 关于类的定义的描述中错误的是( )。 类的定义格式分为说明部分和实现部分...
*5.6 C++处理字符串的方法——字符串类与字符串变量 5.6.1 字符串变量的定义和引用 5.6.2 字符串变量的运算 5.6.3 字符串数组 5.6.4 字符串运算举例 习题 第6章 指针 6.1 指针的概念 6.2 变量与指针 6.2.1 定义...