引用对象、友元、按引用传递、初始化引用、堆栈序列生成器[C++ In Action][5]

引用(reference)
1. 声明引用变量的方法是在类型名后面加一个&符号,实际上&与变量名捆绑使用,如:string &str;
2. 一个引用指向一个对象,是现有对象的别名
3. 一旦创建了引用并初始化引用某特定对象,那么它将总是引用此对象
4. 常量引用不能用于更改它所引用的对象
5.对常量的引用可以用其他任何引用来初始化,非常量引用不能通过一个常量的引用来初始化
6. 如果一个引用保存在某对象中,它必须在此对象构造函数的前导中初始化
7. 当一个方法的形式参数定义为一个引用时,我们说它是按引用方式传递
8. 常量引用只能用于读取
9. 引用在创建时必须初始化,或在其声明中完成;或对于成员引用,在构造函数的前导中完成;或者调用一个带有引用的方
    法时,在调用时完成

StackSeq has-access-to IStack

/*******************************Header file: stackseq.h****************************/
/*程序:序列生成器头文件
 */
#if   ! defined(_080117_STACK_H_)
#define _080117_STACK_H_

const   int  maxStack = 5 ;
class  IStack
{
    friend 
class StackSeq; //类StackSeq是类IStack的朋友
public:
    IStack() : _top(
0{}
    
void Push(int i);
    
int Pop();
private:
    
int _arr[maxStack];
    
int _top;
}
;

class  StackSeq
{
public:
    
//通过一个对常量IStack的引用调用StackSeq构造函数
    StackSeq(IStack const &stack) : _iCur(0), _stack(stack) {} //初始化引用
    bool AtEnd() const;
    
void Advance(); 
    
int GetNum() const
private:
    IStack 
const &_stack//引用stack //常量引用不能更改它所引用的对象(如本例中的TheStack对象)
    int _iCur; //stack当前索引
}
;

#endif 
//  end of _080117_STACK_H

/*******************************Source file: stackseq.cpp****************************/
/*程序:序列生成器源文件
/*目的:逐个返回保存在对象IStack中的值
/*方法:为了从堆栈中回读值,序列生成器需访问堆栈的私有数据成员
/*        堆栈可以序列生成器成为自己的友元而授权对它的访问
 */
#include  " stackseq.h "
#include 
< cassert >
#include 
< iostream >

void  IStack::Push( int  i)
{
    
assert(_top<maxStack);
    _arr[_top]
=i;
    
++_top;
}


int  IStack::Pop()
{
    
assert(_top>0);
    
--_top;
    
return _arr[_top];
}


bool StackSeq::AtEnd() 
const
{
    
return _iCur==_stack._top//友元:可以访问_top 
    
//常量引用只能用于读取。_stack为常量引用,不能通过它更改_top的值
    
//_stack.Push(4); //error //由于Push不是一个常量方法,编译器不允许StackSeq调用_stack.Push()
}


void  StackSeq::Advance()
{
    
assert(!AtEnd());
    
++_iCur;
}


int  StackSeq::GetNum()  const
{
    
assert(!AtEnd());
    
return _stack._arr[_iCur]//友元:可以访问_arr 
    
//常量引用只能用于读取。_stack为常量引用,不允许在此数组中进行写入操作
}


void  main()
{
    IStack TheStack;
    TheStack.Push(
1);
    TheStack.Push(
2);
    TheStack.Push(
3);
    
//for(A;B;C)
    
//Expression A: 初始化,只在进入循环前执行一次
    
//Expression B: 逻辑测试,每次进入循环体时执行测试
    
//Expression C: 改值
    
//for(;;)永远执行
    for(StackSeq seq(TheStack); !seq.AtEnd(); seq.Advance()
    
{
        std::cout
<<" "<<seq.GetNum()<<std::endl;
    }

}

输出结果:
1
2
3

转载于:https://www.cnblogs.com/JCSU/articles/1045047.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值