C++explicit关键字详解
⾸先, C++中的explicit关键字只能⽤于修饰只有⼀个参数的类构造函数, 它的作⽤是表明该构造函数是显⽰的, ⽽⾮隐式的, 跟它相对应的另
⼀个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式).
那么显⽰声明的构造函数和隐式声明的有什么区别呢? 我们来看下⾯的例⼦:
class CxString // 没有使⽤explicit关键字的类声明, 即默认为隐式声明
{
public:
char *_pstr;
int _size;
CxString(int size)
{
_size = size; // string的预设⼤⼩
_pstr = malloc(size + 1); // 分配string的内存
memt(_pstr, 0, size + 1);
}
CxString(const char *p)
{
int size = strlen(p);
_pstr = malloc(size + 1); // 分配string的内存
strcpy(_pstr, p); // 复制字符串
_size = strlen(_pstr);
}
/
/ 析构函数这⾥不讨论, 省略...
};
// 下⾯是调⽤:
CxString string1(24); // 这样是OK的, 为CxString预分配24字节的⼤⼩的内存
CxString string2 = 10; // 这样是OK的, 为CxString预分配10字节的⼤⼩的内存
CxString string3; // 这样是不⾏的, 因为没有默认构造函数, 错误为: “CxString”: 没有合适的默认构造函数可⽤
CxString string4("aaaa"); // 这样是OK的
CxString string5 = "bbb"; // 这样也是OK的, 调⽤的是CxString(const char *p)
CxString string6 = 'c'; // 这样也是OK的, 其实调⽤的是CxString(int size), 且size等于'c'的ascii码
string1 = 2; // 这样也是OK的, 为CxString预分配2字节的⼤⼩的内存
string2 = 3; // 这样也是OK的, 为CxString预分配3字节的⼤⼩的内存
string3 = string1; // 这样也是OK的, ⾄少编译是没问题的, 但是如果析构函数⾥⽤free释放_pstr内存指针的时候可能会报错, 完整的代码必须重载运算符"=", 并在
上⾯的代码中, "CxString string2 = 10;" 这句为什么是可以的呢? 在C++中, 如果的构造函数只有⼀个参数时, 那么在编译的时候就会有⼀
男头像背影个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象. 也就是说 "CxString string2 = 10;" 这段代码, 编译器⾃动将整型转
换为CxString类对象, 实际上等同于下⾯的操作:
CxString string2(10);
或
CxString temp(10);
CxString string2 = temp;
但是, 上⾯的代码中的_size代表的是字符串内存分配的⼤⼩, 那么调⽤的第⼆句 "CxString string2 = 10;" 和第六句 "CxString string6 =
'c';" 就显得不伦不类, ⽽且容易让⼈疑惑. 有什么办法阻⽌这种⽤法呢? 答案就是使⽤explicit关键字. 我们把上⾯的代码修改⼀下, 如下:
class CxString // 使⽤关键字explicit的类声明, 显⽰转换
{
public:
char *_pstr;
int _size;
explicit CxString(int size)
{
_size = size;
// 代码同上, 省略...
}
CxString(const char *p)
{
// 代码同上, 省略...
}
秋后的蚂蚱歇后语
};
// 下⾯是调⽤:
手机发热严重
CxString string1(24); // 这样是OK的
CxString string2 = 10; // 这样是不⾏的, 因为explicit关键字取消了隐式转换
CxString string3; // 这样是不⾏的, 因为没有默认构造函数
CxString string4("aaaa"); // 这样是OK的
CxString string5 = "bbb"; // 这样也是OK的, 调⽤的是CxString(const char *p)
CxString string6 = 'c'; // 这样是不⾏的, 其实调⽤的是CxString(int size), 且size等于'c'的ascii码, 但explicit关键字取消了隐式转换
string1 = 2; // 这样也是不⾏的, 因为取消了隐式转换
string2 = 3; // 这样也是不⾏的, 因为取消了隐式转换
string3 = string1; // 这样也是不⾏的, 因为取消了隐式转换, 除⾮类实现操作符"="的重载
explicit关键字的作⽤就是防⽌类构造函数的隐式⾃动转换.
上⾯也已经说过了, explicit关键字只对有⼀个参数的类构造函数有效, 如果类构造函数参数⼤于或等于两个时, 是不会产⽣隐式转换的, 所以explicit关键字也就⽆效了. 例如:
class CxString // explicit关键字在类构造函数参数⼤于或等于两个时⽆效蒸鱼豉油怎么读
{
public:
char *_pstr;
int _age;
int _size;什么是易经
explicit CxString(int age, int size)
{
_age = age;
_size = size;
// 代码同上, 省略...
}
CxString(const char *p)
{
// 代码同上, 省略...
}
};
// 这个时候有没有explicit关键字都是⼀样的
但是, 也有⼀个例外, 就是当除了第⼀个参数以外的其他参数都有默认值的时候, explicit关键字依然有效, 此时, 当调⽤构造函数时只传⼊⼀个参数, 等效于只有⼀个参数的类构造函数, 例⼦如下:
class CxString // 使⽤关键字explicit声明
{
public:
int _age;
int _size;
建国大业观后感300字
explicit CxString(int age, int size = 0)
{
_age = age;
_size = size;
// 代码同上, 省略...
}
CxString(const char *p)
{
// 代码同上, 省略...
}
};
// 下⾯是调⽤:
CxString string1(24); // 这样是OK的
CxString string2 = 10; // 这样是不⾏的, 因为explicit关键字取消了隐式转换
CxString string3; // 这样是不⾏的, 因为没有默认构造函数
string1 = 2; // 这样也是不⾏的, 因为取消了隐式转换
如何处理人际关系>银针粉
string2 = 3; // 这样也是不⾏的, 因为取消了隐式转换
string3 = string1; // 这样也是不⾏的, 因为取消了隐式转换, 除⾮类实现操作符"="的重载