抽象数据类型(顺序栈)、断言、包含头文件、内联函数、非内联成员函数[C++ In Action][4]...

1. C++中的接口与实现思想, 即类的定义、数据成员的定义、函数原型在接口文件中进行, 实现代码放在实现文件中
2. 函数调用开销:调用前要先保存寄存器,并在返回点恢复;复制实参;程序必须转入一个新位置执行
3. 内联的目的是为了避免函数调用开销。函数指定为内联函数后,通常是将它在程序中每个调用点上"内联地"展开
4. 内联函数的优点是不用函数调用就能隐藏数据,仅此而已
5. inline关键字只是告诉编译器,函数可以内联展开执行,编译器可以自由选择是否内联
6. 非成员函数声明为内联在函数前面加关键字inline,这种函数被声明为内联函数后,其定义(or implementation)最好放在头文件中,除非此函数只在单个的源文件中使用。不放在头文件中,在其它源文件中调用此内联函数在连接时会出错。
7. 被隐式声明为内联:(1)定义出现在类定义中的成员函数;(2)被编译器创建的构造、析构、拷贝构造函数、赋值操作运算
8. 内联函数应在头文件中定义,这样可以确保在调用函数时使用相同的定义,并且保证在调用点该函数的定义对编译器可见
   不适合做内联函数的情况:递归调用、函数包含循环如(for,while等)、函数代码过大
9. 如果将成员函数的定义放在类定义的外面,就像下面的Pop一样,它将自动成为非内联。当然如果你仍然想使之内联,你
   必须在其定义的前面添加关键字inline。在这种情况下,必须记住,当编译器编译调用此函数的代码时,它必须访问此定义
   (而不仅仅是访问类中的声明)。这就是为什么这样的定义通常放在由调用者包含的头文件中的原因

/****************************Header file: stack.h***********************/
# if   ! defined(_080117_STACK_H_) //防止头文件被重复编译, 也可用#ifndef _080117_STACK_H_
#define _080117_STACK_H_

const   int  maxStack = 5 ; //const告诉编译器, maxStack的值永远不会改变
class  IStack
{
public:
    IStack():_top(
0{} //初始化堆栈顶部索引为0
    void Push(int i);
    
int Pop(); //该函数在类外定义时被声明为内联函数,此时不要把inline加在此函数的声明前面
    int 
Count() return _top; } //Count()的执行在类IStack的定义中, 因此它被隐式声明为内联函数
   
int GetTop() return _arr[_top-1]; } //GetTop()的执行在类IStack的定义中, 因此它被隐式声明为内联函数
private:
    
int _arr[maxStack]; //数组的大小必须为常量, 当数组为显式初始化时, 不必指定其大小
    
int _top;
}
;

#endif 
//  end of _080117_STACK_H

/****************************Source file: stack.cpp***********************/
#include  " stack.h " //包含自定义头文件
#include 
< cassert >
#include 
< iostream >

  ///成员函数的定义在类的外面时,它的名字必须带有类名加双冒号,如 IStack::
  //通过NDEBUG=1编译去掉断言,只要没有定义NDEBUG,此断言就会检查它的参数的逻辑真实性,断言失败表明程序有漏洞
void  IStack::Push( int  i) //Push方法的定义在类的外面,因此该方法自动变成了非内联方法(函数)
{
    
assert(_top<maxStack); //断言检查
    _arr[_top]
=i;
    
++_top;
    std::cout
<<"Element "<<i<<" is pushed into stack!\n";
}


inline 
int  IStack::Pop() //Pop方法的定义在类的外面,通过在该定义的前面加inline变成了内联方法(函数)
{
    
assert(_top>0);
    
--_top;
    
return _arr[_top];
}

 
void  main()
{
    IStack stack;

    stack.Push(
1);
    stack.Push(
2);

    std::cout
<<"Top element "<<stack.GetTop()<<std::endl; //内联展开后等价于stack._arr[_top-1]
    std::cout
<<"Count "<<stack.Count()<<std::endl; //内联展开后等价于stack._top

    std::cout
<<"Popped "<<stack.Pop()<<std::endl;
    std::cout
<<"Popped "<<stack.Pop()<<std::endl;

    std::cout
<<"Call top when out of boundrary! "<<stack.GetTop()<<std::endl;
    std::cout
<<"Count "<<stack.Count()<<std::endl;
}

输出结果:
Element 1 is pushed into stack!
Element 2 is pushed into stack!
Top element 2
Count 2
Popped 2
Popped 1
Call top when out of boundrary! -858993460
Count 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值