认识 C++ 中的 explicit 关键字

合集下载

c++中 explicit关键字的含义和用法

c++中 explicit关键字的含义和用法

上面的所有的操作即是所谓的"隐式转换".
如果要避免这种自动转换的功能,我们该怎么做呢?嘿嘿这就是关键字explicit的作用了,将类的构造函数声明为"显示",也就是在声明构造函数的时候 前面添加上explicit即可,这样就可以防止这种自动的转换操作,如果我们修改上面的MyClass类的构造函数为显示的,那么下面的代码就不能够编 译通过了,如下所示:
{
public:
MyClass( int num );
}
....
MyClass obj = 10; //ok,convert int to MyClass
在上面的代码中编译器自动将整型转换为MyClass类对象,实际上等同于下面的操作:
MyClass temp(10);
MyClass obj = temp;
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;}
The implicit type conversion of const char * to a string object enables its users to write the following:string s;s = "Hello";The compiler implicitly transforms this intostring s;//pseudo C++ code:s = string ("Hello"); //create a temporary and assign it to sOn the other hand, if you declare this constructor explicit, you have to use explicit type conversion:class string{//...public:explicit string(const char *);};int main(){string s;s = string("Hello"); //explicit conversion now requiredreturn 0;}Extensive amounts of legacy C++ code rely on the implicit conversion of constructors. The C++ Standardizationcommittee was aware of that. In order to not make existing code break, the implicit conversion was retained. However, anew keyword, explicit, was introduced to the languageto enable the programmer to block the implicit conversionwhen it is undesirable. As a rule, a constructor that can be invoked with a single argument needs to be declaredexplicit. When the implicit type conversion is intentional and well behaved, the constructor can be used as animplicit conversion operator.

explicit 用法

explicit 用法

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语言的32个关键字及其含义

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  中 explicit关键字的含义和用法

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

构造函数explicit

构造函数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个关键字详解

c语言32个关键字详解

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的用法

c++中explicit的用法

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++编程中,显式构造函数是一个非常有用的特性,它可以有效地避免一些潜在的问题,提高代码的可靠性和可维护性。

explicit,implicit,operator 重载运算符

explicit,implicit,operator 重载运算符
identifier Something。
注意:
转换运算符将源类型转换为目标类型。源类型提供转换运算符。与隐式转换不同,必须通过强制转换的方式来调用显式转换运算符。如果转换操作可能导致异常或丢失信息,则应将其标记为 explicit。这可以防止编译器无提示地调用可能产生无法预见后果的转换操作。
conv-typ种形式声明了用户定义的重载内置运算符的运算符。并非所有内置运算符都可以被重载(请参见可重载的运算符)。op-type 和 op-type2 中至少有一个必须是封闭类型(即运算符所属的类型,或理解为自定义的类型)。例如,这将防止重定义整数加法运算符。
后两种形式声明了转换运算符。conv-type-in 和 conv-type-out 中正好有一个必须是封闭类型(即,转换运算符只能从它的封闭类型转换为其他某个类型,或从其他某个类型转换为它的封闭类型)。
运算符只能采用值参数,不能采用 ref 或 out 参数。
C# 要求成对重载比较运算符。如果重载了==,则也必须重载!=,否则产生编译错误。同时,比较运算符必须返回bool类型的值,这是与其他算术运算符的根本区别。
public static explicit operator conv-type-out ( conv-type-in operand )
参数:
result-type 运算符的结果类型。
unary-operator 下列运算符之一:+ - ! ~ ++ — true false
op-type 第一个(或唯一一个)参数的类型。
explicit 关键字用于声明必须使用强制转换来调用的用户定义的类型转换运算符。
implicit 关键字用于声明隐式的用户定义类型转换运算符。如果转换过程可以确保不会造成数据丢失,则可使用该关键字在用户定义类型和其他类型之间进行隐式转换。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

认识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"; // 好;此时允许隐式转换
}。

相关文档
最新文档