c++ void*指针理解和应用

编程入门 行业动态 更新时间:2024-10-10 16:17:55

c++ void*<a href=https://www.elefans.com/category/jswz/34/1768268.html style=指针理解和应用"/>

c++ void*指针理解和应用

c++ void*指针理解和应用

void*说明

void指针不指向任何数据类型,它属于一种未确定类型的过渡型数据。如果要访问实际存在的数据,必须将void指针强转成为指定一个确定的数据类型的数据,如int*、string*、Person*等。

void* p=nullptr;int *a=nullptr;
p=a;double *b=nullptr;
p=b;Person *per = new Person;
p = per;char c[16]={0};
p=c;void* 就像一张白纸,任何类型的指针都可以直接赋值给void*类型的指针;但是反过来int *a=nullptr;
a=p;         //err
a=(int *)p;//需要强制类型转换Person *person2 = nullptr;
person2  = (Person *)p;

2.void指针只支持几种有限的操作:
a.与另一个指针进行比较;
b.向函数传递void
指针或从函数返回void指针;
c.给另一个void
指针赋值。

3.不允许使用void指针操作它所指向的对象,例如,不允许对void指针进行解引用。不允许对void*指针进行算术操作。例如:

几种常用的应用

1.函数传参时不确定类型,或者要支持多类型的传参

void function(int dataType, void* data) {// 根据dataType的不同值,进行不同的转换switch (dataType) {case 0:int* a = (int*)data;case 1:char* a = (char*)data;...}
}

2.当函数的返回值不考虑类型指关心大小的时候

void * memcpy(void *dest, const void *src, size_t len);
void * memset ( void * buffer, int c, size_t num );
//memcpy和memset对外接收任何类型的指针,这样是合理并且必要的,因为这是内存操作函数,
//是对bit进行操作的,考虑数据类型是没有任何意义的。

*2.关于delete void指针
1.void
指向简单的系统内建类型直接只用delete void
,比如下面代码所示:

void* p=nullptr;int *a=nullptr;
p=a;double *b=nullptr;
p=b;delete p;

2.void*所指向的对象在析构函数里要释放,进行此造作会丢失内存,因为它不执行析构函数,比如下面以下代码

class CEntity
{
public:CEntity(char flag);void setData(void *data);void setFlag(char flag);~CEntity();
private:void * m_data;char   m_flag;
};CEntity::CEntity(char flag)
{m_flag = flag;cout<<"constructing entity "<<m_flag<<endl;;
}void CEntity::setData(void *data)
{m_data = data;}void CEntity::setFlag(char flag)
{m_flag = flag;
}CEntity::~CEntity()
{cout<<"destructing entity "<<m_flag<<endl;delete m_data;
}//以上这个类是没什么问题的,但是看以下的调用:
int main(int argc, char *argv[])
{CEntity * a = new CEntity();int ivalue = 5;int *pivalue = &ivalue;a->setFlag(true);a->setData(pivalue);delete a;CEntity * b = new CEntity();int ivalue2 = 6;int *pivalue2 = &ivalue2;b->setFlag(true);b->setData(pivalue2);void *vb = b;delete vb;return 0;
}

我们关心他的输出:

其输出为:  constructing entity adestructing entity aconstructing entity  b                               
可见,delete b 的时候没有释放m_data所指向的内存,没有执行析构函数。
这样会造成内存泄漏。
那么如何释放指向对象类型的void*指针呢?需要强制转换类型,然后进行delete。```cppCEntity * b = new CEntity('b');int ivalue2 = 6;int *pivalue2 = &ivalue2;b->setData(pivalue2);void *vb = b;//delete vb;delete (CEntity*)vb;其输出为: constructing entity adestructing entity aconstructing entity  b destructing entity b

如果b对象的setData(a)这样使用,如何释放b对象内存呢、答案是b对象可以正常调用析构函数,但是其成员变量void指向的a对象内存永远释放不掉。因为delete a时会调用a的析构函数,在析构函数中本身类不知道void的真正的类型,所以delete void*时不会调用b的析构函数。代码和程序结果运行如下:

int main(int argc, char *argv[])
{CEntity * a = new CEntity('a');int ivalue = 5;int *pivalue = &ivalue;a->setData(pivalue);CEntity * b = new CEntity('b');b->setData(a);void *vb = b;delete (CEntity*)vb;return 0;
}其输出为:  constructing entity adestructing entity aconstructing entity  b 

故类中的成员尽可能避免使用void变量,否则在类对象指针传入时会造成析构时void无法正确释放。

更多推荐

c++ void*指针理解和应用

本文发布于:2024-03-12 10:30:30,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1731311.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:指针   void

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!