C++中的void类型

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C++中的void类型
Technorati 标签: ,
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;
};。

相关文档
最新文档