【ThinkingInC++】49、带内联函数的Stash

Stash4.h

/**
* 书本:【ThinkingInC++】
* 功能:带内联函数的Stash
* 时间:2014年9月12日08:16:13
* 作者:cutter_point
*/
#ifndef STASH4_H_INCLUDED
#define STASH4_H_INCLUDED

#include "../require.h"
#include <iostream>

class Stash
{
    int size;       //每个空间存储块的字节长度
    int quantity;   //内部定义的数据类型的存储块的个数
    int next;       //下一个空的内存块的索引
    unsigned char* storage; //存储空间的大小
    void inflate(int increase); //空间不够用的时候增加空间大小
public:
    //构造函数,使用内联函数提高代码执行效率
    Stash(int sz) : size(sz), quantity(0), next(0), storage(0) {}
    Stash(int sz, int initQuantity) : size(sz), quantity(0), next(0), storage(0){inflate(initQuantity);}

    ~Stash()     //回收内存空间
    {
        if(storage != 0)
            delete [] storage;
        std::cout<<"~Stash()     回收内存空间"<<std::endl;
    }

    int add(void* element); //添加元素
    void* fetch(int index) const
    {
        require(0 <= index, "Stash::fetch (-)index");

        if(index >= next)
            return 0;   //超出内存空间的大小

        return &(storage[index*size]);
    }

    int count() const {return next;}

};

#endif // STASH4_H_INCLUDED

Stash4.cpp

/**
* 书本:【ThinkingInC++】
* 功能:带内联函数的Stash
* 时间:2014年9月12日08:17:14
* 作者:cutter_point
*/

#include "Stash4.h"
#include <cassert>
#include <iostream>

using namespace std;

const int increment=100;

//    void inflate(int increase); //空间不够用的时候增加空间大小
//    int add(void* element); //添加元素

void Stash::inflate(int increase)//空间不够用的时候增加空间大小
{
    //判定increase是大于0的
    assert(increase >= 0);
    //判断是否是等于0,如果等于0那就直接返回不用增加
    if(increase == 0) return;
    //大于0 的话
    //1、求得新空间的总个数
    int newQuantity=quantity+increase;
    //2、新空间需求的字节数
    int newBytes=newQuantity*size;
    //3、申请新空间需求的内存
    unsigned char* b=new unsigned char[newBytes];
    //4、吧旧的空间的数据转化到新空间上
    //首先要只要旧的成员数据直接数
    int oldBytes=quantity*size;
    //移动到新的上
    for(int i=0 ; i<oldBytes ; ++i)
        b[i]=storage[i];
    //5、内存回收
    delete [](storage);
    //6、新空间的成员数据更新
    storage=b;
    quantity=newQuantity;
}

//    int add(void* element); //添加元素,并返回最后一个元素的位置
int Stash::add(void* element)
{
    //判断能不能添加,空间够不够
    if(next >= quantity)
        inflate(increment);
    //找到要添加的开始位置
    int startBytes=next*size;
    //吧element转化成unsigned char*的数组
    unsigned char* e=(unsigned char*)element;
    //添加元素到数据类型中
    for(int i=0 ; i<size ; ++i) //一个元素的字节长度,就是添加一个元素的长度
        storage[startBytes+i]=e[i];
    //吧next更新
    ++next;
    //返回位置
    return (next-1);
}

Stash4Test.cpp

/**
* 书本:【ThinkingInC++】
* 功能:带内联函数的Stash
* 时间:2014年9月12日08:18:19
* 作者:cutter_point
*/

#include "Stash4.cpp"
#include "../require.h"
#include <fstream>
#include <iostream>
#include <string>

using namespace std;

int main()
{
    Stash intStash(sizeof(int));    //就是转化成int类型

    for(int i=0 ; i<100 ; ++i)  //吧0到99存入到这个数据类型的数组中
        intStash.add(&i);

    //全部输出看看
    for(int j=0 ; j<100 ; ++j)
        cout<<"intStash.fetch("<<j<<")="
            <<*(int*)intStash.fetch(j)<<endl;

    //再创建一个长度为80的字符串数组,每个字符串长度都是80个字节
    const int bufsize=80;
    Stash stringStash(sizeof(char)*bufsize, 100);
    ifstream in("Stash4Test.cpp");
    assure(in, "Stash4Test.cpp");
    string line;
    while(getline(in, line))
    {
        stringStash.add((char*)line.c_str());   //吧字符串转化成char*存入到数组中
    }

    //输出来看看
    int k=0; //计数
    char* cp;   //指向每一个string的地址
    while((cp=(char*)stringStash.fetch(k++)) != 0)
        cout<<"stringStash.fetch("<<k<<")="<<cp<<endl;

    return 0;
}

最后我们看一看关于枚举类型的知识

枚举类型直接输出里面的字符

http://topic.csdn.net/t/20050408/19/3921153.html

#include <iostream>
 #include <string>
 #include <map>
 using namespace std;

 enum MPType
 {
 MPT_None,
 MPT_Other,
 MPT_Board,
 MPT_Length
 }; 

//方案一,直接用数组

 string MPTypeString[MPT_Length] = {
 "MPT_None ",
 "MPT_Other ",
 "MPT_Board "
 }; 

//方案二,用map

 class MPTypeConverter {
 public:
 MPTypeConverter() {
 map.insert(make_pair(MPT_None,"MPT_None "));
 map.insert(make_pair(MPT_Other,"MPT_Other "));
 map.insert(make_pair(MPT_Board,"MPT_Board "));
 }

string ToString(MPType key) {
 MPTypeStringMap::iterator pos =map.find(key);
 if (pos != map.end())
 return pos-> second;
 return string( " ");
 }

 private:
 typedef map <MPType, string>MPTypeStringMap;
 MPTypeStringMap map;
 };

 int main()
 {
 MPTypeConverter converter;
 cout < < MPTypeString[MPT_Board]< < endl;
 cout < < converter.ToString(MPT_Board)< < endl;
 return 0;
 } 
时间: 2024-12-10 14:13:22

【ThinkingInC++】49、带内联函数的Stash的相关文章

【ThinkingInC++】50、带内联函数的Stack

Stack4.h /** * 书本:[ThinkingInC++] * 功能:带内联函数的Stack * 时间:2014年9月16日19:04:01 */ #ifndef STACK4_H_INCLUDED #define STACK4_H_INCLUDED #include "../require.h" class Stack { struct Link //节点结构 { void* data; //数据用空指针,为了后面方便存储各种数据都可以转化 Link* next; //指向下

带参宏定义和inline修饰的内联函数

带参宏定义和inline修饰的内联函数都是在编译时,用函数体替换掉宏调用或函数调用.这样用的好处是减少调用函数所花费的时间. 例如: 算法导论在讲到堆排序时说的,好的堆排序实现一般是把Left(i),Right(i),Parent(i)的实现通过宏定义或内联函数来实现,这就是因为当我们对一组数据使用堆排序时,会大量的调用left,right,parent函数定义成宏或内敛函数之后既不影响我们的代码阅读性又能是代码运行速度更快!

内联函数详解

什么是内联性和外联函数 类的成员函数可以分为内联函数和外联函数.内联函数是指那些定义在类体内的成员函数,即该函数的函数体放在类体内.而说明在类体内,定义在类体外的成员函数叫外联函数.外联函数的函数体在类的实现部分. 内联函数在调用时不是像一般的函数那样要转去执行被调用函数的函数体,执行完成后再转回调用函数中,执行其后语句,而是在调用函数处用内联函数体的代码来替换,这样将会节省调用开销,提高运行速度. 内联函数与前面讲过的带参数的宏定义进行一下比较,它们的代码效率是一样的,但是内联函数要优于宏定义

宏定义与内联函数

1.宏定义的规则和使用解析(1)宏定义的解析规则就是:在预处理阶段由预处理器进行替换,这个替换是原封不动的替换.(2)宏定义替换会递归进行,直到替换出来的值本身不再是一个宏为止.(3)一个正确的宏定义式子本身分为3部分:第一部分是#dedine ,第二部分是宏名 ,剩下的所有为第三部分.(4)宏可以带参数,称为带参宏.带参宏的使用和带参函数非常像,但是使用上有一些差异.在定义带参宏时,每一个参数在宏体中引用时都必须加括号,最后整体再加括号,括号缺一不可. 宏定义示例1:MAX宏,求2个数中较大的

拷贝构造,深度拷贝,关于delete和default相关的操作,explicit,类赋初值,构造函数和析构函数,成员函数和内联函数,关于内存存储,默认参数,静态函数和普通函数,const函数,友元

 1.拷贝构造 //拷贝构造的规则,有两种方式实现初始化. //1.一个是通过在后面:a(x),b(y)的方式实现初始化. //2.第二种初始化的方式是直接在构造方法里面实现初始化. 案例如下: #include<iostream> //如果声明已经定义,边不会生成 class classA { private: int a; int b; public: //拷贝构造的规则,有两种方式实现初始化 //1.一个是通过在后面:a(x),b(y)的方式实现初始化 //2.第二种初始化的方式是直

【转】ios内联函数 inline

ios内联函数 inline 缘由 由于在学习使用UIScrollVew开发的过程中,碰到下面这个属性(设置内边距): @property(nonatomic) UIEdgeInsets scrollIndicatorInsets; // default is UIEdgeInsetsZero. adjust indicators inside 1 光看UIEdgeInsets这个类型,一时还不知道它的具体内部结构是怎么样的,于是继续点进去发现它的定义如下: typedef struct UIE

深入探讨 内联函数和宏定义的区别

内联函数的执行过程与带参数宏定义很相似,但参数的处理不同.带参数的宏定义并不对参数进行运算,而是直接替换:内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算求值,然后把表达式的值传递给形式参数. 内联函数与带参数宏定义的另一个区别是,内联函数的参数类型和返回值类型在声明中都有明确的指定:而带参数宏定义的参数没有类型的概念,只有在宏展开以后,才由编译器检查语法,这就存在很多的安全隐患. 使用内联函数时,应注意以下问题: 1)内联函数的定义性声明应该出现在

C/C++之宏、内联函数和普通函数的区别

内联函数的执行过程与带参数宏定义很相似,但参数的处理不同.带参数的宏定义并不对参数进行运算,而是直接替换:内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算求值,然后把表达式的值传递给形式参数. 内联函数与带参数宏定义的另一个区别是,内联函数的参数类型和返回值类型在声明中都有明确的指定:而带参数宏定义的参数没有类型的概念,只有在宏展开以后,才由编译器检查语法,这就存在很多的安全隐患. 使用内联函数时,应注意以下问题:     1)内联函数的定义性声明应

(转)内联函数

(1)什么是内联函数?内联函数是指那些定义在类体内的成员函数,即该函数的函数体放在类体内. (2)为什么要引入内联函数?当然,引入内联函数的主要目的是:解决程序中函数调用的效率问题.另外,前面我们讲到了宏,里面有这么一个例子:#define ABS(x) ((x)>0? (x):-(x))当++i出现时,宏就会歪曲我们的意思,换句话说就是:宏的定义很容易产生二意性. 我们可以看到宏有一些难以避免的问题,怎么解决呢?前面我们已经尽力替换了. 下面我们用内联函数来解决这些问题. (3)为什么inli