Technorati 标签: void,指针

1.1. void类型

void类型其实是一种用于语法性的类型,而不是数据类型,主要用于作为函数的参数或返回值,或者定义void指针,表示一种未知类型。

1.1.1. 作为函数参数与返回值

void func( void );

void func( );

例如上面两例,其实两种声明方式是等效的,在C++中如果参数列表为空,默认的参数类型即为void,但建议没有参数时使用void以提高程序的可读性。

因 为C++在定义函数时不允许返回值类型为空,在C++98之前,是允许定义函数时不定义返回值的,默认的返回值是int类型。其实默认int类型并不是好 事,如果函数有返回值在函数返回时是需要消耗CPU传递返回值的,也或许也是C++98标准将默认返回值类型改为void的原因。

因为C++不允许默认返回值,所以当函数不需要返回值是,需要将返回值类型声明为int类型。当调用返回值类型为void类型的函数时,在工程上有很多实际代码在前面加上(void)类型转换,以提高代码的可读性。如调用上面定义的 func函数。

(void)func( );

从另一个角度讲,这样严谨的方式是可以提高软件的健壮性的,调用函数时可以明确地看出是没有返回值的,如果调用一个返回值不是int类型的函数时最好判断其返回值,以检查函数调用是否成功,如:

#include

char buff[5];

func( );

snprintf(buff, sizeof(buff), “%d”, “10240”);

显 然这段代码是有问题的,当然func没有返回值,这样调用是没有问题,但snprintf的调用会有问题因为缓冲区有可能太小而不能容纳结果字符串,上面 的代码就有这个问题。假设我们不知道snprintf有没有返回值,可能这个BUG我们不会发现,直到有一天出现了我们不期望的结果。如果我们严格要求调 用每个函数时必须判断函数的返回值,按照以下面的代码编码,就不会出给我们的程序造成隐患。

#include

#include

char buff[5];

(void)func( );

if( sizeof(buff) <= snprintf(buff, sizeof(buff), "%d", 10240) ){

buff[sizeof(buff) - 1] = '/0';

throw std::overflow_error("buff overflow");

}

1.1.2. void指针

void* pv = NULL;

string str = "string";

int i = 1;

pv = &str;

pv = &i;

int *pi = (int*)pv;

string* ps = (string*)pv;

如 上面的示例所示,void指针表示未知类型的指针,可以将任意类型的指针直接赋值给void指针,好比是C#、Java中的object引用,可以把任意 类型的对象赋值给它。但把void类型赋值给特定类型的指针时,就需要进行强制转换,因为C++为类型语言,尽可能保证类型安全,如果使用了强制类型转 换,编译器就认为程序员知道他(她)在干什么,程序也应该负起这样做的责任。

值得注意的是,函数指针与类成员的指针不能赋值给void*类型变量。

void* 在C语言中一般用于动态内存的操作,因为malloc和calloc返回的类型都是void*类型。在W3C的协议库libwww里,大量使用了 void*类型,如果使用C++的继承特性的话,应该会使代码可读性更好。而在C++中则可以使用new返回特定类型指针,更不容易出现问题,所以 void*的作用显得更弱了。

void*在C++中的主要作用就是作为函数指针的返回值[C++ Programming Language],例如:

void* my_alloc(size_t size);

void* 还用于一些底层的操作,例如我们有两个类UdpSocket和TcpSocket,在我们一个传输类中需要支持两种协议,提供统一的接口,但 UdpSocket和TcpSocket之间没有继承关系,无法使用共同的基类指针,而只能使用void*指针,代码如[??]。

class UdpSocket{};

class TcpSocket{};

class Transfer

{

public:

enum Protocol { UDP, TCP };

Transfer(Protocol prot) : _prot(prot)

{

if( _prot == UDP)

_sock = new UdpSocket( );

else if( _prot == TCP )

_sock = new TcpSocket( );

else

throw std::invalid_argument("prot");

}

~Transfer( void )

{

if(_prot == UDP)

delete (UdpSocket*)_sock;

else

delete (TcpSocket*)_sock;

_sock = NULL;

}

private:

void* _sock;

Protocol _prot;

};

转载于:https://www.cnblogs.com/zhoug2020/p/5416772.html

C++中的void类型相关推荐

  1. 如何理解 C# 中的 System.Void 类型?

    咨询区 ordag 我知道方法声明成 void 表示不返回什么东西,但我发现在 C# 中 void 不仅仅是一个关键词,而且还是一个真实的类型. void 是 System.Void 的别名,就像 i ...

  2. 关于空指针(指针指向为NULL)和void类型的指针的理解

    正在学C,书上老说空指针,或者说void指针,对于我这样的生手来说,理解非常容易造成混淆,因为void这个单词的意思也是空,到底空指针的意思是指指向地址为空的类型呢,还是指void类型的指针呢 (1) ...

  3. 为什么要在JavaScript中使用静态类型? (使用Flow进行静态打字的4部分入门)

    by Preethi Kasireddy 通过Preethi Kasireddy 为什么要在JavaScript中使用静态类型? (使用Flow进行静态打字的4部分入门) (Why use stati ...

  4. .NET中可空值类型实现原理

    为了让.Net中的值类型可以赋值为null,微软特地添加了Nullable<T>类型,也可简写为T?.但是Nullable<T>自身是结构体,也是值类型,那么它是如何实现将nu ...

  5. C++中的string 类型占几个字节

    C++中的string 类型占几个字节 一:先看一道面面试题: 题目是要求输出:TrendMicroSoftUSCN 然后要求修改程序,使程序能输出以上结果.代码如下: #include <io ...

  6. c++中的void指针和const指针

    在c++中可以声明指向void类型的指针,指向void类型的指针称为void指针,此外,在声明指针时,还可以用关键字const进行修饰,用关键字const修饰的指针称为const指针. 1.void指 ...

  7. C/C++中的函数中的void和void* 理解

    C/C++中的void和void* 一.void void关键字表示"空类型"的概念.但是,这里的"空类型"不表示"任意类型",而是表示不存 ...

  8. C#中的值类型和引用类型

    文章目录 1 C#中的值类型 1.1 值类型示例程序 1.2 值类型(基本数据类型)的变量使用特点 2 C#中的引用类型 2.1 引用类型数据程序示例 2.2 引用数据类型的变量使用特点 3 变量类型 ...

  9. c语言中指针的类型,学习C语言中的指针类型

    摘要:结合我院学生十年来参加全国计算机等级考试(C语言部分)情况,通过分析成绩分布与题型关系,我们发现指针方面的题型失分率最高.在此基础上结合教学实际,本文提出学习指针知识的方法和顺序过程,并将其应用 ...

  10. Winform中实现序列化指定类型的对象到指定的Xml文件和从指定的Xml文件中反序列化指定类型的对象

    场景 在Winform程序中需要将某些页面的设置存储到配置文件中,下次再次打开时通过配置文件读取,点击确定时能将将设置保存到配置文件中. 之前介绍过 Winform中自定义xml配置文件后对节点进行读 ...

最新文章

  1. 限定项目的 Node.js 版本
  2. linux c 运行报错 killed
  3. Silverlight Downloads
  4. java预期_预期. java的
  5. Eigen入门之密集矩阵 3 - Array操作
  6. Linux Supervisor 守护进程基本配置
  7. 项目实战|100个蓝牙接收器发货了
  8. 在windows环境下ftp服务器的文件上传和下载
  9. signature=d5d679bcec778027f40bcf8a2796c61b,Processing damaged items using image data lift
  10. PYTORCH BN层
  11. linux开发环境搭建(4)-从SD卡启动uboot
  12. 汪学明导师—商业模式创新与转型专家
  13. 使用代理爬去微信公众号_使用代理处理反爬抓取微信文章
  14. C#Skip和Take的用法
  15. 蓝桥杯真题——猜年龄python讲解
  16. cesium 模型实体平移
  17. AARRR(海盗模型)|原理+Python可视化实现
  18. 【Android开发】计算机网络基础知识点,如何完成网络请求过程?
  19. Groovy Xml解析
  20. 方舟服务器自动维护,明日方舟剿灭关卡积水潮窟地图分析 干员选择与站位推荐[多图]...

热门文章

  1. 同质化代币和非同质化代币 区别对比
  2. C++ boost共享锁 unique_lock shared_lock
  3. DevOps使用教程 华为云(10)GitHub git Pull Request 合并请求
  4. Docker教程小白实操入门(10)--如何删除一个镜像
  5. 微信小程序云开发教程-一个js文件如何包含多个云函数
  6. ubuntu定时任务cron 访问网址php
  7. JavaSE——Java8之Stream流
  8. 拥塞避免算法、快重传、快恢复、慢启动
  9. 银联支付java代码实现_Java后端实现三方支付集成支付宝、微信、银联、光大、邮政支付...
  10. java线程的状态改变(练习)