void*能接受那些类型?
inline int EG::ByteLocator::Locate(void* identifier,int i_length)
{
while(curIndex<dataSize)
{
if(memcmp(identifier,&srcBuffer[curIndex],i_length)==0)
{
curIndex+=i_length;
return curIndex;
}
curIndex+=step;
}
return -1;
}
我写了这样一个函数
在调用时,这样写
int end=locator.Locate((void*)0x00,1);
1.为什么这样写会报内存错误啊?void* 不可以接受任何类型吗?
#ifndef EG_MEMORY_H
#define EG_MEMORY_H
#include"EG/EGDef.h"
#include<memory.h>
#ifdef __cplusplus
extern "C"{//声明为C编译,连接方式为外部函数
#endif
namespace EG{
typedef EG::byte dataType;
class EG_API ByteLocator
//字节定位器
{
private:
dataType* srcBuffer;
int curIndex;
int step;
int dataSize;
ByteLocator(const ByteLocator&);
ByteLocator& operator=(const ByteLocator&);
public:
ByteLocator(dataType* srcBuffer,int srcSize,int curIndex=0,int step=1);
int Locate(dataType* identifier,int i_length);
int Locate(void* identifier,int i_length);
int Locate(byte4 identifier,int i_length=4);
/*
*如果找到标识数据,则返回数据末端的索引
*如果没有找到标识数据,返回负值
*/
void operator+(int val);
void operator-(int val);
int setIndex(int Index);
int setStep(int step);
int GetIndex();
int GetStep();
};
};
inline void EG::ByteLocator::operator+(int val)
{
this->curIndex=curIndex+val;
}
inline void EG::ByteLocator::operator-(int val)
{
this->curIndex=curIndex-val;
}
inline int EG::ByteLocator::setIndex(int Index)
{
if((Index>=dataSize)||(Index<0))
return EXCEPTION;
this->curIndex=Index;
return OK;
}
inline int EG::ByteLocator::setStep(int step)
{
if(step==0)
return EXCEPTION;
this->step=step;
return OK;
}
inline int EG::ByteLocator::GetIndex(){ return curIndex;}
inline int EG::ByteLocator::GetStep() { return step;}
inline int EG::ByteLocator::Locate(void* identifier,int i_length)
{
while(curIndex<dataSize)
{
if(memcmp(identifier,&srcBuffer[curIndex],i_length)==0)
{
curIndex+=i_length;
return curIndex;
}
curIndex+=step;
}
return -1;
}
#ifdef __cplusplus
}
#endif
#endif
2. 内联与不内联的原则,大家觉得我这样写好吗? c c++ 内联
[解决办法]
1.因为读写地址0会触发操作系统内存管理模块报异常
2.inline只能建议而不能强制编译器内联
3.不是只能把内联函数放在头文件中。可以把他们编译到dll或者lib中(但参考第2条)
[解决办法]
1,If a pointer's type is void *, the pointer can point to any variable that is not declared with the const or volatile keyword. 地址0x0属于NULL指针分配的分区,不可读写
2,inline的目的在于以少量的指令空间代价换取函数调用代价;所以如果函数执行体执行相对时间远大于函数调用相对时间,就不应该Inline,即使inline申请,编译器也不一定内联。
3,都属于二进制文件 可以使用
[解决办法]
内联要求在每一个编译单元存在定义,你把定义放在 cpp 里面,其他地方没有了,可不是出错吗。
[解决办法]
也就是因为这个原因,所以说内联函数经常放在头文件中,每个需要用的cpp都包含此文件。定义一个数组 初始化为 0 传递进去不就行了吗。难道有错?
[解决办法]
这是满足要求的一种方法,也是最常用的。c++ 的规定内联函数必须在每个编译单元存在定义,如果一个内联函数定义在 a.h 声明,实现在 a.cpp,又在 b.cpp 中被调用,后者只 #include a.h。那么 b.cpp 的编译单元中就不存在该内联函数的定义,根据标准的要求,已经是编译错误了,至于 a.cpp 中存在该函数(无论是否内联)定义的事实不影响认定错误的判断。我见过的内联就三种写法:
1. 头文件中声明函数时同时提供定义。最常用最简单的。
2. 头文件先声明函数,过一会又在同样的文件提供了定义,须加 inline 关键字。主楼的写法。
3. 头文件声明,定义写在 .cpp 里面,只不过头文件末尾 #include .cpp,实际上是 2. 的变体。类模板库常见。
4. 头文件声明,定义在 cpp,头文件不 include cpp,调用端 include .h and .cpp,这还是 2. 的变体,而且是自找麻烦的风格。
至于你在 #4 说的像通常那样,把定义和声明分开写,调用端只需要包含声明的用法,是恰恰不能满足标准的,因此是错误。
[解决办法]
是的,你仔细想想这是有道理的。所谓将实现编译成库,目的就是调用端只需要知道接口而不需要关心实现,这样的逻辑导致了调用端编译时不需要看到定义,只需要生成跳转;而内联函数的全部作用就是为了将实现代码在调用端编译器展开从而避免跳转,如果编译器看不到内联函数的定义,那它怎么可能实现内联展开呢,编译器也不是神,它那知道要具体展开成什么啊。所以内联函数的精神和动态库的精神背道而驰,他们肯定在源码层不能共享相同的机制。