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 <cstdio></cstdio>
char buff[5];
func( );
snprintf(buff, sizeof(buff), “%d”, “10240”);
显然这段代码是有问题的,当然func没有返回值,这样调用是没有问题,但snprintf的调用会有问题因为缓冲区有可能太小而不能容纳结果字符串,上面的代码就有这个问题。假设我们不知道snprintf有没有返回值,可能这个BUG我们不会发现,直到有一天出现了我们不期望的结果。如果我们严格要求调用每个函数时必须判断函数的返回值,按照以下面的代码编码,就不会出给我们的程序造成隐患。
#include <cstdio></cstdio>
#include <stdexcept></stdexcept>
char buff[5];
(void)func( );
if( sizeof(buff)
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;
};
分享到:
相关推荐
C++数据类型及取值范围 1.基本数据类型: ①字符类型:char(字符型) 例:‘A’,’b’ ②整数类型:int(整型) 例:4563, 234, 885634 ③浮点类型:float(单精度型)、double(双精度型) 例:3.1456 , 0.9e12 ④空值...
许多初学者对C/C++语言中的void及void指针类型不甚理解,因此在使用上出现了一些错误。本文将对void关键字的深刻含义进行解说,并详述void及void指针类型的使用方法与技巧。
在C++中实现属性 本文译自http://www.codeguru.com/cpp_mfc/Property.html的Implementing a Property in C++ 以下是译文 本文由Emad Barsoum投稿。 开发测试环境:Visual C++ 7.0, Windows XP sp1, Windows 2000...
C++中文头文件 中文关键字定义 还有快捷函数库 例如 全套进程提权() 函数 即可获取所有令牌权限(共35个令牌) 还有基本的文件流 void 写入文件(路径,字符,类型) string 读取文件(路径)
c语言和c++的几种基本语言类型,C语言包含5个基本数据类型: void, integer, float, double, 和 char.
与C#和Java等托管语言不同,C++是静态类型的,不支持反射或匿名委托,这使得事件系统稍微困难一些。本项目试图创建一个简单、轻量级的事件框架,可以轻松地适应任何C++11项目。唯一的要求是支持C++11和访问标准C++库...
今天在写程序的时候,出现了一个错误 “对象包含与成员函数不兼容的类型限定符”,从... 您可能感兴趣的文章:C++中const用法小结C和C++ const的声明差异C++ 中const和复合类型C++中的const和constexpr详解C++编程中的co
//C#调用C++的DLL搜集整理的所有数据类型转换方式,可能会有重复或者多种方案,自己多测试 //c++:HANDLE(void *) —- c#:System.IntPtr //c++:Byte(unsigned char) —- c#:System.Byte //c++:SHORT(short) —- c#...
C++中还包括wchar_t数据类型,wchar_t也是字符类型,但是是那些宽度超过8位的数据类型。许多外文字符集所含的数目超过256个,char字符类型无法完全囊括。wchar_t数据类型一般为16位。 标准C++的iostream类库中包括...
通过C++语言中的继承机制,一个新类既可以共享另一个类的操作和数据,也可以在新类中定义已有类中没有的成员。 class CBase { public: void FuncA(void); void FuncB(void); }; //派生类 class CDerive :...
二:bool是标准C++数据类型,可取值true和false。单独占一个字节,如果数个bool对象列在一起,可能会各占一个bit,这取决于编译器。 BOOL是微软定义的typedef int BOOL。与bool不同,它是一个三值逻辑,TRUE/...
在C++中标识符区分大小写,另外标识符不能和C++中的关键字相同,也不能和函数同名。 4.声明 将一个标识符引入一个作用域,此标识符必须指明类型,如果同时指定了它所代表的实体,则声明也是定义。
许多初学者对C/C++诧言中的void及void指针类型丌甚理解,因此在使用上出现了一些错诨。本文将对void关键字的深刻含义迚行解说,并详述void及void指针类型的使用方法不技巧。
void __stdcall bcdtohex(BYTE b,BYTE *buf); bool __stdcall hextostring(unsigned char *inbuf,int inlen,unsigned char * outbuf); bool __stdcall stringtohex(unsigned char *inbuf,int inlen,unsigned char * ...
动态数组类模板Array C++ //数组类模板声明 ... //T类型指针,存放动态分配的数组内存首地址 int size; void Error(ErrorType error, int badIndex = 0)const; //错误处理函数 }; ................
在c++中int main()和int main(void...在c语言中main()省略返回类型也就相当说明返回类型为int型,不过这种用法在c++中逐渐被淘汰。虽然Void main()在很多系统都适用,但他毕竟不是标准的,所以应该避免这种用法
4.6 C++中所有的变量和函数都必须有类型 6 4.7新增Bool类型关键字 6 4.8三目运算符功能增强 6 5 C/C++中的const 6 1 const基础知识(用法、含义、好处) 6 2 C中“冒牌货” 6 3 const和#define相同之处 6 4 const和#...
标准C++包含一个显式的转换语法: static_cast:用于“良性”和“适度...static_cast:用于所有明确定义的转换,包括void*的强制转换、隐式类型转换、类层次的静态定位。 1. 数据类型由小到大的转换,比如int转换为long
3.2.6 void函数中的return语句 77 3.2.7 前提条件和执行结果 78 3.2.8 main函数 79 3.2.9 递归函数 79 3.3 作用域规则 80 3.3.1 局部变量 80 3.3.2 过程抽象 82 3.3.3 全局常量与全局变量 83 3.3.4 语句块 ...
virtual void Write(const char *str, const int &grade;); public: Log(); ~Log(); virtual std::string LogTime(); void WriteLog(const char *str, const int &grade; = 0); void WriteLog(const std::...