C++类,按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象。
对于一个参数的构造函数加上explicit关键字可以避免类的隐式转换带来的使用上的误解。
例如:
以下是没有加explicit关键字的一个类。
#include "stdafx.h"
#include "assert.h"
class CDataBufMgr
{
public:
unsigned int Size() const
{
return m_nSize;
}
const char* Data() const
{
return m_pData;
}
CDataBufMgr(unsigned int nSize)
{
m_pData = NULL;
m_nSize = nSize;
m_pData = new char[m_nSize];
}
CDataBufMgr(char *pData,unsigned int nSize)
{
m_pData = NULL;
m_nSize = nSize;
m_pData = pData;
}
virtual ~CDataBufMgr()
{
if (m_pData)
{
delete []m_pData;
m_pData = NULL;
m_nSize = 0;
}
}
private:
char *m_pData;
unsigned int m_nSize;
};
int _tmain(int argc, _TCHAR* argv[])
{
CDataBufMgr classData(10); //正确的表意
CDataBufMgr classData1 = 10; //能编译通过,是隐式转换的结果,但容易造成误解。
return 0;
}
下面这种情况是加了关键字explicit:
#include "stdafx.h"
#include "assert.h"
class CDataBufMgr
{
public:
unsigned int Size() const
{
return m_nSize;
}
const char* Data() const
{
return m_pData;
}
explicit CDataBufMgr(unsigned int nSize) //这里加上了关键字
{
m_pData = NULL;
m_nSize = nSize;
m_pData = new char[m_nSize];
}
CDataBufMgr(char *pData,unsigned int nSize)
{
m_pData = NULL;
m_nSize = nSize;
m_pData = pData;
}
virtual ~CDataBufMgr()
{
if (m_pData)
{
delete []m_pData;
m_pData = NULL;
m_nSize = 0;
}
}
private:
char *m_pData;
unsigned int m_nSize;
};
int _tmain(int argc, _TCHAR* argv[])
{
CDataBufMgr classData(10); //正确的表达意思
CDataBufMgr classData1 = 10; //编译不通过
return 0;
}
编译结果:
1>------ Build started: Project: TestSomthing, Configuration: Debug Win32 ------
1>Compiling...
1>TestSomthing.cpp
1>e:\学习实践\testsomthing\testsomthing\testsomthing.cpp(51) : error C2440: 'initializing' : cannot convert from 'int' to 'CDataBufMgr'
1> Constructor for class 'CDataBufMgr' is declared 'explicit'
1>Build log was saved at "file://e:\学习实践\TestSomthing\TestSomthing\Debug\BuildLog.htm"
1>TestSomthing - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
总结:
因些,C++设计类的时候,如果有一个参数的构造函数,应该加上explicit关键字,避免这种不利的隐式转换。