认识 C++ 中的 explicit 关键字
- 格式:docx
- 大小:12.42 KB
- 文档页数:2
explicit 用法explicit关键字作用:禁止隐式调用类的单参数的构造函数。
上述实际上由两种情形:1. 禁止隐式调用拷贝构造函数2. 禁止类对象之间的隐式转换。
类对象间的隐式转换:利用一个已经存在的其他类型的对象来创建本类的新对象,且不显示调用本类的构造函数。
案例:#include <iostream>using namespace std;class A{public:A(){num = 9000;}A(int n){this->num = n;}A(const A&a){num = a.num;}friend void show(const A&);private:int num;};void show(const A& a){cout << "a.num = "<< a.num << endl;}int main(){// 隐式调用类A的单参的构造器cout << "Hello world!" << endl;A a1 = 5000;//调用隐式转换构造器A a2 = a1;//调用隐式拷贝构造器show(a1);show(a2);show(6000);return 0;}上述隐式调用C++语法是允许的,但很多人对这种表示方式不习惯,觉得程序的可读性较差。
为了禁止对类的单参数构造器的隐式调用,C++引入关键字explicit。
在类的定义中,在任何一个单参数构造器前加explicit,即可以禁止对该构造器的隐式调用。
案例:#include <iostream>using namespace std;class A{public:A(){num = 0;}explicit A(int n){this->num = n;}explicit A(const A& a){num = a.num;}friend void show(const A&);private:int num;};void show(const A& a){cout << " variable:" << a.num << endl;}int main(){//cout << "Hello world!" << endl;A a1(32);A a2(a1);show(a1);show(a2);show(A(6000));return 0;}这样程序既可以正常运行,并具有更好的可读性。
c语言的32个关键字及其含义C语言是一门广泛应用于计算机编程的高级编程语言,其简洁、高效的特点使之成为许多程序员的首选。
而C语言的关键字则是构成C语言语法结构的基石,掌握这些关键字的含义对于编写高质量的C代码至关重要。
本文将会介绍C语言的32个关键字及其含义。
一、自动变量(auto)auto关键字用于声明自动变量,自动变量是在代码块中定义的变量。
它们的生命周期仅限于所在代码块,函数的参数也属于自动变量。
二、断言(assert)assert关键字用于在程序运行时进行断言验证,如果断言条件为假,程序将会中止执行。
断言通常用于调试和排错。
三、带宽限定(band)band关键字用于限定带宽,常用于定义延迟函数、外部中断和总线访问等场景。
四、布尔类型(bool)bool关键字用于声明布尔类型的变量,布尔类型只有两个值:真和假。
一般用于判断语句和循环语句的条件。
五、跳过(break)break关键字用于跳出循环或者switch语句块,提前终止程序的执行。
六、函数调用(call)call关键字用于向函数传递参数并调用函数。
它与return关键字相对应,后者用于从函数返回结果。
七、case标签(case)case关键字用于定义switch语句中不同分支的标签,根据不同的条件执行相应的代码。
八、常量(const)const关键字用于声明常量,常量值在程序执行期间不可更改。
通常用于定义不变的特定值,提高代码的可读性和可维护性。
九、continue(continue)continue关键字用于结束当前循环的当前迭代,并进入下一轮循环的迭代。
通常用于跳过某些不满足条件的循环迭代。
十、默认(default)default关键字用于定义switch语句中默认分支的代码块。
如果没有匹配的case 标签,将会执行默认分支的代码。
十一、定义(define)define关键字用于定义宏。
宏是一种在程序编译之前被展开的符号常量或者代码片段。
c++中的explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?如果c++类的构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象,如下面所示:class MyClass{public:MyClass( int num );}....MyClass obj = 10; //ok,convert int to MyClass在上面的代码中编译器自动将整型转换为MyClass类对象,实际上等同于下面的操作:MyClass temp(10);MyClass obj = temp;上面的所有的操作即是所谓的"隐式转换".如果要避免这种自动转换的功能,我们该怎么做呢?嘿嘿这就是关键字explicit的作用了,将类的构造函数声明为"显示",也就是在声明构造函数的时候前面添加上explicit即可,这样就可以防止这种自动的转换操作,如果我们修改上面的MyClass类的构造函数为显示的,那么下面的代码就不能够编译通过了,如下所示:class MyClass{public:explicit MyClass( int num );}....MyClass obj = 10; //err,can‘t non-explict convertclass isbn_mismatch:public std::logic_error{public:explicit isbn_missmatch(const std::string &s):std:logic_error(s){}isbn_mismatch(const std::string &s,const std::string &lhs,const std::string &rhs):std::logic_error(s),left(lhs),right(rhs){}const std::string left,right;virtual ~isbn_mismatch() throw(){}};Sales_item& operator+(const Sales_item &lhs,const Sales_item rhs){if(!lhs.same_isbn(rhs)) throw isbn_mismatch("isbn missmatch",lhs.book(),rhs.book());Sales_item ret(lhs);ret+rhs;return ret;}Sales_item item1,item2,sum;while(cinitem1item2){try{ sun=item1+item2;}catch(constisbn_mismatch &e){ cerre.what()"left isbn is:"e.left"right isbn is:"e.rightendl;}}用于用户自定义类型的构造函数,指定它是默认的构造函数,不可用于转换构造函数。
构造函数explicit在C++中,构造函数是一种特殊的成员函数,用于初始化类的对象。
通常情况下,我们可以使用默认构造函数来创建对象,但有时我们可能需要限制隐式构造函数的使用,以避免不必要的对象创建。
这就是explicit构造函数的作用。
explicit构造函数是一种修饰符,用于限制隐式类型转换的发生。
它只能用于带有一个参数的构造函数,用于明确告诉编译器不要进行隐式类型转换。
为了更好地理解explicit构造函数的用途和工作原理,下面我将探讨其概念、用法和适用场景。
概念:explicit构造函数是在构造函数声明前加上explicit关键字的构造函数。
这样的构造函数只能用于显式创建对象,不能用于隐式类型转换。
当我们将一个值传递给通过explicit修饰的构造函数时,编译器不会进行自动类型转换。
用法:下面是一个使用explicit构造函数的例子:```class MyClasspublic:explicit MyClass(int value) : m_value(value) {}int m_value;};```在这个例子中,我们定义了一个类MyClass,它有一个带有int参数的构造函数。
通过在构造函数前加上explicit关键字,我们明确告诉编译器不要进行隐式类型转换。
这意味着我们只能使用显式的方式来创建MyClass的对象,例如:```MyClass obj = MyClass(10); // 显式创建对象MyClass obj2 = 10; // 隐式创建对象,编译错误```适用场景:使用explicit构造函数有以下几个典型的应用场景:1. 避免不必要的隐式类型转换:有时候,我们可能不希望一些类型的对象能够被隐式地转换成其他类型的对象。
通过使用explicit构造函数,我们可以明确告诉编译器不进行隐式类型转换,从而增加代码的可读性和安全性。
```class Stringexplicit String(int size) : m_size(size) {}private:int m_size;};void printString(const String& str)std::cout << str << std::endl;int maiprintString(10); // 隐式类型转换,编译错误printString(String(10)); // 显式创建对象return 0;```2. 避免二义性问题:有时候,如果一个类有多个构造函数,且参数类型相似,编译器可能无法确定应该调用哪个构造函数。
c语言32个关键字详解auto: auto关键字是c语言中用来声明局部变量的修饰符,它能够使程序员在一个函数的内部定义一个局部变量。
auto关键字的作用是使得这个局部变量在函数返回后不会消失,而是可以在函数的外部继续存在。
break: break关键字用于强制跳出循环,它可以用于while,do while或者for循环。
当它出现在循环内部时,循环立即终止,并且控制流程将会跳转到循环外部。
case: case关键字可以用来创建一个条件分支,并且它必须出现在switch语句中。
它可以使得程序不必以多重if语句来处理多重分支问题。
char: char关键字用来指定字符变量,它可以表示一个字符或者一个小整数,一般8位字节足以存放一个字符。
const: const关键字用来定义常量,它之后的变量不能被修改,一旦定义的常量将一直保存在程序的整个执行过程中。
continue: continue关键字用来结束当前迭代循环,并且进入下一次迭代循环。
当它出现在循环内部时,当前的循环将会立即终止,控制流程将会继续到循环的下一个迭代中。
default: default关键字用来指定switch中的默认case语句,当没有任何case匹配成功时,将会执行default后面的语句。
do: do关键字用来声明一个do-while循环,do-while循环通常用来保证在程序中某个条件至少被执行一次,它的基本形式为“do{}while()”,执行流程大致如下:首先执行do后面的语句,然后判断while后面的条件是否满足,如果满足,则继续执行do后面的语句,直到while条件不成立。
double: double关键字用来指定双精度浮点类型的变量,它能够表示一个比较大的数字,一般来说8个字节存储就足够了。
else: else关键字用来指定if语句的反条件分支,即当if检查的条件不满足时,会执行else后面的语句。
enum: enum关键字用来指定一组枚举类型的常量,它可以使枚举的常量有规律的递增或者递减,常用于建立某一种特定事物的有限集合。
C++中explicit的用法1. 介绍在C++编程中,explicit是一个关键字,用于修饰构造函数。
它的作用是禁止编译器执行自动类型转换,以避免意外的类型转换造成的不确定性和错误。
在本文中,将对explicit的用法进行详细介绍,并举例说明其在实际编程中的应用。
2. explicit的基本概念在C++中,当一个构造函数只接受一个参数时,它实际上定义了一个从该参数类型到类类型的隐式类型转换。
这种隐式类型转换可能会导致一些潜在的问题,比如不期望的类型转换或者不明确的代码逻辑。
为了解决这些问题,C++11引入了explicit关键字,用于显式声明构造函数为显式构造函数,从而禁止编译器执行隐式类型转换。
3. explicit的使用方法在类的构造函数声明前加上explicit关键字,即可将该构造函数声明为显式构造函数。
例如:```cppclass Test {public:explicit Test(int value) : m_value(value) {}private:int m_value;};```在上面的例子中,Test类的构造函数接受一个int类型的参数,但加上了explicit关键字,表示该构造函数为显式构造函数,禁止编译器执行隐式类型转换。
4. 显式构造函数的优势通过使用explicit关键字声明构造函数,我们可以有效地避免一些潜在的问题,例如:- 避免意外的类型转换:对于只接受一个参数的构造函数,如果不使用explicit关键字,那么它将成为隐式类型转换的候选函数,这可能导致意外的类型转换,从而产生错误的结果。
- 明确代码逻辑:显式构造函数可以使代码的逻辑更加明确,使得代码阅读和维护更加容易。
5. 显式构造函数的应用场景显式构造函数通常适用于以下情况:- 构造函数只接受一个参数,并且该参数不能被隐式转换为类的类型。
- 需要避免意外的类型转换和提高代码的可读性。
6. 总结在C++编程中,显式构造函数是一个非常有用的特性,它可以有效地避免一些潜在的问题,提高代码的可靠性和可维护性。
序号关键字音标意义1 auto 声明自动变量,缺省时编译器一般默认为auto2 int [int] 声明整型变量3 double 声明双精度变量4 long 声明长整型变量5 char 声明字符型变量6 float 声明浮点型变量7 short 声明短整型变量8 signed 声明有符号类型变量9 unsigned 声明无符号类型变量10 struct 声明结构体变量11 union 声明联合数据类型12 enum 声明枚举类型13 static 声明静态变量14 switch 用于开关语句15 case 开关语句分支16 default 开关语句中的“其他”分支17 break 跳出当前循环18 register 声明寄存器变量19 const constant['kɑnstənt] 声明只读变量 const是constant的缩写形式20 volatile 说明变量在程序执行中可被隐含地改变21 typedef [taip] [def] 用以给数据类型取别名(当然还有其他作用)22 extern 声明变量是在其他文件正声明(也可以看做是引用变量)23 return 子程序返回语句(可以带参数,也可不带参数)24 void 声明函数无返回值或无参数,声明空类型指针25 continue 结束当前循环,开始下一轮循环26 do 循环语句的循环体27 while 循环语句的循环条件28 if 条件语句29 else 条件语句否定分支(与if 连用)30 for 一种循环语句(可意会不可言传)31 goto 无条件跳转语句32 sizeof 计算对象所占内存空间大小。
c语言合法关键字的定义C语言是一种广泛使用的编程语言,它具有丰富的关键字来定义和描述程序的结构、语义和行为。
本文将详细介绍C语言的合法关键字定义,并逐步解释这些关键字的用途和特性。
首先,我们需要了解什么是关键字。
关键字是编程语言中具有特定含义和用途的保留字,它们不能作为标识符使用,并且用来定义特定的语法和语义规则。
在C语言中,关键字是预先定义的,不能重新定义或修改它们的含义。
C语言的关键字总共有32个。
它们是:auto、break、case、char、const、continue、default、do、double、else、enum、extern、float、for、goto、if、int、long、register、return、short、signed、sizeof、static、struct、switch、typedef、union、unsigned、void、volatile、while。
接下来,我们将以这些关键字为主题,一步一步回答这个问题。
1. auto:auto关键字用于声明自动变量,即函数内定义的局部变量。
自动变量在函数调用结束后会被销毁。
2. break:break关键字用于在循环语句(如for、while和do-while)中提前终止循环,并跳出循环体。
3. case:case关键字用于在switch语句中定义每个分支的标签,用于匹配不同的条件。
4. char:char关键字用于声明字符类型的变量。
字符类型变量存储单个字符的ASCII码值。
5. const:const关键字用于声明常量。
常量的值在程序运行期间不可修改。
6. continue:continue关键字用于终止当前迭代,并开始下一次迭代。
7. default:default关键字用于在switch语句中定义默认情况下的分支。
8. do:do关键字用于定义do-while循环,即先执行循环体再判断条件。
9. double:double关键字用于声明双精度浮点类型的变量。
认识C++ 中的explicit 关键字
(Danny Kalev发表于2004-12-28 11:01:04)
带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:
class C {
int i;
//...
public:
C(int i);//constructor and implicit conversion operator
//as well
};
void f() {
C c(0);
c = 5; //将5 隐式转换为C 对象,然后赋值
}
编译器重新编辑上述例子代码,如下:
//////////////////////////////////////////////////////////////////////////////////////////
//"c=5;" 被编译器转换成下面这个样子:
/////////////////////////////////////////////////////////////////////////////////////////
C temp(5);// 实例化一个临时对象,
c = temp; // 用= 赋值
temp.C::~C(); // temp 的析构函数被激活
在很多情况下,这个转换是有意的,并且是正当的。
但有时我们不希望进行这种自动的转换,例如:
class String {
int size;
char *p;
//..
public:
String (int sz); //这里不希望进行隐式转换操作
};
void f ()
{
String s(10);
// 下面是一个程序员的编码;发生一个意想不到的转换:
s = 100; // 糟糕,100 被转换为一个String,然后被赋值给s
}
为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
class String {
int size;
char *p;
//..
public:
// 不要隐式转换
explicit String (int sz);
String (const char *s, int size n = 0); // 隐式转换
};
void f ()
{
String s(10);
s = 100; // 现在编译时出错;需要显式转换:
s = String(100); // 好;显式转换
s = "st"; // 好;此时允许隐式转换
}。