MemoryBlock这个类是用来对freenos内存管理的
头文件:
#ifndef __MEMORYBLOCK_H
#define __MEMORYBLOCK_H
#include "Types.h"
class MemoryBlock
{
public:
/**
* Fill memory with a constant byte.
* @param dest Memory to write to.
* @param ch Constant byte.
* @return Pointer to dest.
*/
static void * set(void *dest, int ch, unsigned count);
/**
* Copy memory from one place to another.
* @param dest Destination address.
* @param src Source address.
* @param count Number of bytes to copy.
* @return Number of bytes copied.
*/
static Size copy(void *dest, const void *src, Size count);
/**
* Copy a character string.
*/
static Size copy(char *dest, char *src, Size count);
/**
* Compare memory.
*/
static bool compare(void *dest, void *src, Size count);
/**
* Compare memory.
*
* @param p1 Memory pointer one.
* @param p2 Memory pointer two.
* @param count Number of bytes to compare or zero to continue until a ZERO byte.
* @return True if equal, false otherwise.
*/
static bool compare(const char *p1, const char *p2, Size count = 0);
};
#endif /* __MEMORYBLOCK_H */
- 看头文件我们可以看到freenos的MemoryBlock提供了5个函数:
- static void * set(void *dest, int ch, unsigned count);
set函数的功能和c语言的memset相似,给一块指定大小的内存设置一个值
dest:目标内存的地址
ch:要给内存设置的值
count:设置内存的大小
- static Size copy(void *dest, const void *src, Size count);
copy函数是将一块指定大小的内存中的值,拷贝到另外一块内存中,功能和memcpy类似
param1:目标内存的首地址
param2:被拷贝的内存的首地址
param3:要拷贝内存地址的大小
- static Size copy(char *dest, char *src, Size count);
copy函数是将一块指定长度字符串的值,拷贝到另外一个字符串中,功能和strcpy类似
param1:目标字符串的首地址
param2:被拷贝的字符串的首地址
param3:要拷贝字符串的长度
- static bool compare(void *dest, void *src, Size count);
compare函数是比较两块指定大小的内存的值是否相同
param1:目标内存块的首地址
param2:被比较内存块的首地址
param3:要内存块的大小
- static bool compare(const char *p1, const char *p2, Size count = 0);
compare函数是比较两个指定长度的字符串是否相同
param1:目标字符串的首地址
param2:被比较的字符串的首地址
param3:要比较字符串的长度
- 从头文件可以学习到的技巧:
1、巧用static关键字
从头文件我们可以发现这几个方法其实都是static类型的,这样做的好处就是我们不需要在使用的时候每次都第一个MemoryBlock的对象,通过.的方法来调用,直接通过MemoryBlock::作用域的方式就可以访问,其实很多时候都有这样的困惑,就是有些时候对某些类型的操作我们并不需要封装成类,不然使用起来很麻烦,在freenos中对MemoryBlock的操作,其实给我们提供了一种很好的方法,那就是通过static对成员函数就行修饰,这样相当于给MemoryBlock的这一系列方法加了一个命名空间。使用的时候更像是在调用一个c风格的函数。
2、接口的设计
观察上面的五个成员函数,我们可以发现,copy和compare这两个函数,作者进行了重载,其实copy和compare char版本可以用void也可以实现,但是我们在平时的使用中很多时候其实操作的是字符串,所以为char专门提供一个方法,这样就可以少去强制转换的过程。但是作者在这个地方参数感觉设计不是很合理,因为按理说被拷贝对象应该都是const类型,这样才能保证在函数内部不会被修改,而且也可以告诉使用者,但是作者copy的char版本的第二个参数却不是const修饰的,还有一点就是compare函数按理来说应该是两个参数应该都是const类型的,但是void版本的却不是,还有就是返回值,其实都有待商榷*,copy的返回值void应该是void,char版本的应该是char
MemoryBlock的实现:
/*
#include "Macros.h"
#include "MemoryBlock.h"
void * MemoryBlock::set(void *dest, int ch, unsigned count)
{
char *temp;
for(temp = (char *) dest; count != 0; count--)
{
*temp++ = ch;
}
return (dest);
}
Size MemoryBlock::copy(void *dest, const void *src, Size count)
{
const char *sp = (const char *)src;
char *dp = (char *)dest;
for(Size i = count; i != 0; i--)
*dp++ = *sp++;
return (count);
}
Size MemoryBlock::copy(char *dst, char *src, Size count)
{
char *d = dst;
const char *s = src;
unsigned n = count;
// Copy as many bytes as will fit
if (n != 0) {
while (--n != 0) {
if ((*d++ = *s++) == '\0')
break;
}
}
// Not enough room in dst, add NUL and traverse rest of src
if (n == 0) {
if (count != 0)
*d = '\0';
while (*s++)
;
}
// Count does not include NUL
return(s - src - 1);
}
bool MemoryBlock::compare(const char *p1, const char *p2, Size count)
{
for (Size i = count; i > 0 || !count; i--)
{
if (!count && (*p1 == ZERO || *p2 == ZERO))
break;
if (*p1 != *p2)
break;
p1++, p2++;
}
return (*p1 == *p2);
}