explicit关键字的作用
关键字explicit的作用
explicit构造函数C++编程语言中有很多比较重要的关键字在实际编程中起着非常重要的作用。
我们今天为大家介绍的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;上面的所有的C++ explicit关键字相关的操作即是所谓的"隐式转换"。
如果要避免这种自动转换的功能,这就是关键字explicit的作用了,将类的构造函数声明为"显式",也就是在声明构造函数的时候前面添加上explicit即可,这样就可以防止这种自动的转换操作,如果我们修改上面的MyClass类的构造函数为显式的,那么下面的代码就不能够编译通过了,如下所示:class MyClass{public:explicit MyClass( int num );}//.MyClass obj = 10; //err,can't non-explict convert以上就是对C++ explicit关键字的相关介绍。
explicit用来防止由构造函数定义的隐式转换。
要明白它的作用,首先要了解隐式转换:可以用单个实参来调用的构造函数定义了从形参类型到该类类型的一个隐式转换。
C++构造函数、复制构造函数和析构函数专题(修订版)
示例:构造函数和Biblioteka 认构造函数#include <iostream> #include <string> using namespace std; class A{public: //void A(){} //A()const{} //A1(){} A(){cout<<"A"<<endl;} A(int i){cout<<"Ai"<<endl;} }; //构造函数一般被声明为公有的,因为主要是用来初始化对象的数据成员的 //错误,构造函数不能反回任何值(包括void类型) //错误,构造函数不能是const或volatile的 //错误,构造函数的名称必须与类名相同。 //正确,构造函数可以有形参也可以没有形参 //正确,可以重载多个构造函数的版本
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关键字作用:禁止隐式调用类的单参数的构造函数。
上述实际上由两种情形: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#常用关键字1)abstract 可以和类、方法、属性、索引器及事件一起使用,标识一个可以扩展但不能被实体化的、必须被实现的类或方法。
2)as 一个转换操作符,如果转换失败,就返回null。
3)base 用于访问被派生类或构造中的同名成员隐藏的基类成员。
4)catch 定义一个代码块,在特定类型异常抛出时,执行块内代码。
参见try和finally。
5)checked 既是操作符又是语句。
确保编译器运行时,检查整数类型操作或转换时出现的溢出。
6)const 标识一个可在编译时计算出来的变量值,即一经指派不可修改的值。
7)delegate 指定一个声明为一种委托类型。
委托把方法封装为可调用实体,能在委托实体中调用。
8)enum 表示一个已命名常量群集的值类型。
9)event 允许一个类或对象提供通知的成员,他必须是委托类型。
10)explicit 一个定义用户自定义转换操作符的操作符,通常用来将内建类型转换为用户定义类型或反向操作。
必须再转换时调用显示转换操作符。
11)extern 标识一个将在外部(通常不是c#语言)实现的方法。
12)finally 定义一个代码块,在程序控制离开try代码快后执行。
参见try和catch。
13)fixed 在一个代码块执行时,在固定内存位置为一个变量指派一个指针。
14)foreach 用于遍历一个群集的元素。
15)goto 一个跳转语句,将程序执行重定向到一个标签语句。
16)implicit 一个操作符,定义一个用户定义的转换操作符。
通常用来将预定义类型转换为用户定义类型或反向操作。
隐式转换操作符必须在转换时使用。
17)interface 将一个声明指定为接口类型,即实现类或构造必须遵循的合同。
18)internal 一个访问修饰符。
19)namespace 定义一个逻辑组的类型和命名空间。
20)operator 用来声明或多载一个操作符。
21)out 标识一个参数值会受影响的参数,但在传入方法时,该参数无需先初始化。
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的使用引导语:C#适合为独立和嵌入式的系统编写程序,从使用复杂操作系统的大型系统到特定应用的小型系统均适用。
以下是店铺整理的c#转换关键词explicit的使用,欢迎参考阅读!explicit 关键字用于声明必须使用强制转换来调用的用户定义的类型转换运算符。
例如,在下面的示例中,此运算符将名为Fahrenheit 的类转换为名为 Celsius 的`类:C#// Must be defined inside a class called Farenheit:public static explicit operator Celsius(Fahrenheit f){return new Celsius((5.0f / 9.0f) * (f.degrees - 32));}可以如下所示调用此转换运算符:C#Fahrenheit f = new Fahrenheit(100.0f);Console.Write("{0} fahrenheit", f.Degrees);Celsius c = (Celsius)f;转换运算符将源类型转换为目标类型。
源类型提供转换运算符。
与隐式转换不同,必须通过强制转换的方式来调用显式转换运算符。
如果转换操作可能导致异常或丢失信息,则应将其标记为 explicit。
这可以防止编译器无提示地调用可能产生无法预见后果的转换操作。
省略此强制转换将导致编译时错误编译器错误 CS0266。
示例下面的示例提供 Fahrenheit 和 Celsius 类,它们中的每一个都为另一个提供显式转换运算符。
C#class Celsius{public Celsius(float temp){degrees = temp;}public static explicit operator Fahrenheit(Celsius c) {return new Fahrenheit((9.0f / 5.0f) * c.degrees + 32); }public float Degrees{get { return degrees; }}private float degrees;}class Fahrenheit{public Fahrenheit(float temp){degrees = temp;}// Must be defined inside a class called Farenheit: public static explicit operator Celsius(Fahrenheit f) {return new Celsius((5.0f / 9.0f) * (f.degrees - 32));}public float Degrees{get { return degrees; }}private float degrees;}class MainClass{static void Main(){Fahrenheit f = new Fahrenheit(100.0f);Console.Write("{0} fahrenheit", f.Degrees);Celsius c = (Celsius)f;Console.Write(" = {0} celsius", c.Degrees);Fahrenheit f2 = (Fahrenheit)c;Console.WriteLine(" = {0} fahrenheit", f2.Degrees);}}/*Output:100 fahrenheit = 37.77778 celsius = 100 fahrenheit*/下面的示例定义一个结构Digit,该结构表示单个十进制数字。
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++编程中,显式构造函数是一个非常有用的特性,它可以有效地避免一些潜在的问题,提高代码的可靠性和可维护性。
C#程序设计及应用教程(第2版)课后答案__人民邮电出版社(马骏、邓居英)
} } }
9、错误和异常有什么区别,为什么要进行异常处理,用于异常处理的语句有哪些? 【解答】
错误是指在执行代码过程中发生的事件,它中断或干扰代码的正常流程并创建异常对象。 当错误中断流程时,该程序将尝试寻找异常处理程序(一段告诉程序如何对错误做出响应的 代码),以帮助程序恢复流程。换句话说,错误是一个事件,而异常是该事件创建的对象。
Console.WriteLine("你输入的字符个数不是 5 个,请重新输入。"); } else {
ok = true; for (int i = 0; i < 5; i++) {
char c = str[i]; if (c < 'A' || c > 'Z') {
Console.WriteLine("第{0}个字符“{1}”不是大写字母,请重新 输入。", i + 1, c);
12.34--1,234.00%good 0--good 456--00456good 5、编写一个控制台应用程序,输出 1 到 5 的平方值,要求:
1) 用 for 语句实现。 2) 用 while 语句实现。 3) 用 do-while 语句实现。 【解答】
using System; using System.Collections.Generic; using System.Text; namespace outputSquareValue {
【解答】
using System; using System.Collections.Generic; using System.Text; namespace testOutput {
Qt中的关键字----explicit
Qt中的关键字----explicit
关键字 explicit 可以禁⽌“单参数构造函数”被⽤于⾃动类型转换,主要⽤于 "修饰 "构造函数. 指明构造函数只能显⽰使⽤,⽬的是为了防⽌不必要的隐式转化.
关键字 explicit 可以禁⽌“单参数构造函数”被⽤于⾃动类型转换。
光看这⼀句似乎不太容易明⽩,下⾯,举个简单地例⼦。
//main.cpp
#include <iostream>
using namespace std;
class Test
{
public:
Test(int a)
{
m_data = a;
}
void show()
{
cout << "m_data = " << m_data << endl;
}
private:
int m_data;
};
void main(void)
{
Test t = 2; // 将⼀个常量赋给了⼀个对象
t.show();
}
编译能够通过,执⾏结果:m_data = 2。
为什么会这样呢?原来C++通过隐式转换,构造了⼀个临时对象Test(2),将它赋给了t(这⾥调⽤了默认的构造函数,⽽不是重载的“=”,因为这是在对象创建的时候)。
那么,如果给构造函数加上关键字 explicit ,构造函数变成了 explicit Test(int a),再次编译,编译器就会报错。
这时,就只能显式地使⽤构造函数了Test t = Test(2) 。
explicit,implicit,operator 重载运算符
注意:
转换运算符将源类型转换为目标类型。源类型提供转换运算符。与隐式转换不同,必须通过强制转换的方式来调用显式转换运算符。如果转换操作可能导致异常或丢失信息,则应将其标记为 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 关键字用于声明隐式的用户定义类型转换运算符。如果转换过程可以确保不会造成数据丢失,则可使用该关键字在用户定义类型和其他类型之间进行隐式转换。
C#关键字详解
1第一部分2访问关键字:base,this3base访问基类的成员。
用于从派生类中访问基类的成员,1.调用基类上已经被重写的方法。
2.指定创建派生类实例时应调用的基类构造函数。
**对基类的访问只能在派生类的构造函数实例的方法实例的属性访问器中。
属性访问器:get,set函数。
注意:!!!!!!!!!不能在静态方法中使用base关键字。
例:在子类的方法中写base.GetInfo();调用基类的方法。
基类中的构造函数重载了,Mybase()和Mybase(int i);在子类的构造函数中public MyDerived():base(int i)public MyDerived(int i):base()this:引用当前对象。
用于引用为其调用方法的当前实例。
静态成员函数没有this指针。
可以用于从构造函数,实例方法,实例访问器中访问成员。
this的一般用途:1.限定被相似的名子隐藏的成员public void A(int a, int b ){this.a=a;this.b=b;}2.将对象作为参数传递到函数中public void ShowInstance(){print(this);console.writeline("lalalalllalalala");}3.声明索引器public int this[int param]{get{ return array[param]; }set{ array[param]=value; }}注意!!!!!!静态方法,静态属性访问器或字段声明中不能用this。
二.转换关键字:explicit, implicit, operator1explicit:用于声明用户定义的显式类型转换运算符。
例:class MyType{public static explicit operator MyType(int i){//从int显式转换成MyType类型的代码!!!}}显式类型转换符必须通过类型转换调用。
c++32个关键字详解
C++ 标准(例如 C++17)定义了一系列关键字,这些关键字在语言中具有特殊的含义,不能被用作标识符或其他用途。
以下是 C++ 标准中的一些关键字,每个关键字都具有特定的语法和语义:1.alignas: C++11 引入的,用于指定内存对齐方式。
2.alignof: C++11 引入的,用于获取类型的对齐要求。
3.and: 逻辑与运算符。
4.and_eq: 位与赋值运算符。
5.asm: 用于嵌入汇编代码。
6.auto: C++11 引入的,用于自动类型推断。
7.bitand: 按位与运算符。
8.bitor: 按位或运算符。
9.bool: 布尔数据类型。
10.break: 用于跳出循环或 switch 语句。
11.case: 用于 switch 语句中的分支。
12.catch: 用于异常处理。
13.char: 字符数据类型。
14.char16_t: C++11 引入的,用于表示 UTF-16 字符。
15.char32_t: C++11 引入的,用于表示 UTF-32 字符。
16.class: 定义类。
pl: 位求补运算符。
18.const: 声明常量。
19.constexpr: C++11 引入的,用于指示表达式在编译时求值。
20.const_cast: 类型转换运算符,用于移除常量性。
21.continue: 继续下一轮循环。
22.decltype: C++11 引入的,用于获取表达式的类型。
23.default: C++11 引入的,用于指定 switch 语句的默认分支。
24.delete: C++11 引入的,用于删除函数或数组元素。
25.do: 循环语句的起始标志。
26.double: 双精度浮点数数据类型。
27.dynamic_cast: 运行时类型转换运算符。
28.else: 条件语句的分支。
29.enum: 枚举类型。
30.explicit: 显式构造函数关键字。
31.export: C++11 引入的,已废弃,不再使用。
c语言的37个关键字及其含义
c语言的37个关键字及其含义C语言是一种广泛使用的编程语言,拥有许多关键字,这些关键字在程序中具有特殊的用途和含义。
下面是C语言的37个关键字及其含义:1. auto:用于声明自动存储类别的局部变量。
2. break:在循环或switch语句中,用于跳出当前循环或switch分支。
3. case:在switch语句中,用于标识不同的选择分支。
4. char:用于声明字符类型的变量或函数。
5. const:用于声明常量,其值不能被修改。
6. continue:用于跳过当前循环迭代,转到下一次迭代。
7. default:在switch语句中,用于定义默认情况的代码块。
8. do:用于创建一个执行语句块直到满足特定条件的循环。
9. double:用于声明双精度浮点数类型的变量或函数。
10. else:在if语句中,用于定义条件不为真时执行的代码块。
11. enum:用于声明枚举类型和枚举常量。
12. extern:用于声明变量或函数是在其他文件或模块中定义的。
13. float:用于声明单精度浮点数类型的变量或函数。
14. for:用于创建一个循环,指定初始条件、循环条件和循环迭代。
15. goto:用于无条件地转移到程序中的标记语句。
16. if:用于执行条件语句块,如果条件为真,则执行代码块。
17. int:用于声明整数类型的变量或函数。
18. long:用于声明长整数类型的变量或函数。
19. register:用于声明寄存器存储类别的局部变量。
20. return:用于从函数中返回值。
21. short:用于声明短整数类型的变量或函数。
22. signed:用于声明有符号数类型的变量或函数。
23. sizeof:用于获取数据类型或变量的大小。
24. static:用于声明静态存储类别的局部变量。
25. struct:用于声明结构体类型和结构体变量。
26. switch:用于多个选择分支的条件语句。
转换构造函数
转换构造函数转换构造函数是一种特殊的构造函数,它可以将一个对象从一种类型转换为另一种类型。
在C++中,转换构造函数是通过使用关键字“explicit”或“implicit”来定义的。
本文将介绍转换构造函数的概念、用法和注意事项。
概念转换构造函数是一种特殊的构造函数,它可以将一个对象从一种类型转换为另一种类型。
转换构造函数可以将一个对象从一种类型转换为另一种类型,也可以将一个对象从一个类转换为另一个类。
转换构造函数的语法如下:class 类名{public:explicit/implicit 类名(参数列表);};其中,explicit和implicit是关键字,用于指定转换构造函数的类型。
explicit表示显式转换,只能通过强制类型转换来调用;implicit表示隐式转换,可以自动调用。
用法转换构造函数可以用于以下情况:1.将一个对象从一种类型转换为另一种类型。
例如,将一个整数转换为一个字符串:class String{public:String(int num){stringstream ss;ss<<num;ss>>str;}private:string str;};2.将一个对象从一个类转换为另一个类。
例如,将一个基类指针转换为一个派生类指针:class Base{public:virtual void func(){}};class Derived:public Base{public:void func(){}};int main(){Base* b=new Derived;Derived* d=dynamic_cast<Derived*>(b);return 0;}注意事项使用转换构造函数时需要注意以下几点:1.转换构造函数必须是公有的。
2.转换构造函数不能有返回值。
3.转换构造函数不能有参数默认值。
4.转换构造函数不能被继承。
5.转换构造函数不能被重载。
C++中常用关键字及其用法
C++中常⽤关键字及其⽤法0.1 C++与C的对⽐1. C++有三种编程⽅式:过程性,⾯向对象,泛型编程。
2. C++函数符号由函数名+参数类型组成,C只有函数名。
所以,C没有函数重载的概念。
3. C++ 在 C的基础上增加了封装、继承、多态的概念4. C++增加了泛型编程5. C++增加了异常处理,C没有异常处理6. C++增加了bool型7. C++允许⽆名的函数形参(如果这个形参没有被⽤到的话)8. C允许main函数调⽤⾃⼰9. C++⽀持默认参数,C不⽀持10. C语⾔中,局部变量必须在函数开头定义,不允许类似for(int a = 0; ;;)这种定义⽅法。
11. C++增加了引⽤12. C允许变长数组,C++不允许13. C中函数原型可选,C++中在调⽤之前必须声明函数原型14. C++增加了STL标准模板库来⽀持数据结构和算法⼀、常⽤的关键字极其⽤法1.1 const主要⽤法C++ 的const关键字的作⽤有很多,⼏乎⽆处不在,⾯试中往往会问“说⼀说const有哪些⽤法”。
下⾯是⼀些常见的const⽤法的总结:除此以外,const的⽤法还有:const引⽤可以引⽤右值,如const int& a = 1;注:1. const 成员⽅法本质上是使得this指针是指向const对象的指针,所以在const⽅法内,2. const 成员函数可以被⾮const和const对象调⽤,⽽const对象只能调⽤const 成员函数。
原因得从C++底层找,C++⽅法调⽤时,会传⼀个隐形的this参数(本质上是对象的地址,形参名为this)进去,所有成员⽅法的第⼀个参数是this隐形指针。
const成员函数的this指针是指向const对象的const指针,当⾮const对象调⽤const⽅法时,实参this指针的类型是⾮const对象的const指针,赋给const对象的const指针没有问题;但是如果const对象调⽤⾮const⽅法,此时实参this指针是指向const对象的const指针,⽆法赋给⾮const对象的const指针,所以⽆法调⽤。
explicit关键字的用法
explicit关键字的用法(原创实用版)目录1.引言2.Explicit 关键字的含义3.Explicit 关键字的使用场景4.Explicit 关键字的作用5.示例6.结论正文【引言】在编程语言中,关键字(keyword)是指被编程语言保留用于特定目的的单词。
在这些关键字中,有一种被称为 explicit 关键字。
本文将详细介绍 explicit 关键字的含义、使用场景、作用以及示例。
【Explicit 关键字的含义】Explicit 关键字通常用于表示显式(explicit)的意思。
在编程语言中,它用于强调某个操作或变量需要显式声明或定义,而不是隐式(implicit)地默认或推断。
【Explicit 关键字的使用场景】Explicit 关键字的使用场景包括但不限于以下几种情况:1.声明变量:在声明变量时,使用 explicit 关键字可以强调变量需要显式声明,而不是隐式推断。
例如,在 C++中,可以使用`explicit`关键字声明一个显式转换的变量。
2.函数参数:在函数参数中使用 explicit 关键字,可以强调该参数需要显式传递,而不是隐式地从函数内部推断。
例如,在 C++中,可以使用`explicit`关键字声明一个显式参数的函数。
3.类型转换:在类型转换中使用 explicit 关键字,可以强调该转换需要显式进行,而不是隐式地进行自动类型转换。
例如,在 C++中,可以使用`explicit`关键字声明一个显式类型转换。
【Explicit 关键字的作用】Explicit 关键字的主要作用是提高代码的可读性和明确性。
通过使用 explicit 关键字,程序员可以清晰地表示某个操作或变量需要显式声明或定义,从而避免因隐式推断导致的错误或混淆。
【示例】以下是一个 C++示例,展示了如何使用 explicit 关键字声明一个显式转换的变量、一个显式参数的函数以及一个显式类型转换:```cpp#include <iostream>// 使用 explicit 关键字声明一个显式转换的变量explicit int explicitVar = 10;// 使用 explicit 关键字声明一个显式参数的函数explicit void explicitFunc(int explicitParam) {std::cout << "Explicit function called with explicit parameter: " << explicitParam << std::endl;}// 使用 explicit 关键字声明一个显式类型转换explicit int explicitConvert(double value) {return value * 2;}int main() {// 调用显式函数explicitFunc(5);// 使用显式转换int result = explicitConvert(3.5);std::cout << "Result of explicit conversion: " << result << std::endl;return 0;}```【结论】总之,explicit 关键字在编程语言中用于强调某个操作或变量需要显式声明或定义,而不是隐式地默认或推断。
explicit关键字
explicit关键字⼀: explicit在QT的开发中,是经常见到的关键字,现在来讲讲下这个关键字的作⽤。
⾸先,类的构造函数⼀般是隐式⾃动转换的,代码如下: class TestMy { public: TestMy() { cout<<"默认构造函数1"<<endl; } TestMy(const char *str) { cout<<"默认构造函数2"<<endl; } TestMy(int size) { mSize=size; cout<<"默认构造函数3"<<endl; } char *name; int mSize; }; void test01() { TestMy str4; //调⽤⽆参数的构造函数,因为TestMy提供了两个带参数的构造函数,这个不提供的话,这样写编译会报错 TestMy str1="abc"; //调⽤的是TestMy(const char *str) TestMy str2(20); //调⽤的是TestMy(int size) TestMy str3=40; //调⽤的是TestMy(int size) TestMy str5='A'; //调⽤的是TestMy(int size),且size等于'A'对应的ASCCI值 } int main() { test01(); return 0; } 运⾏的结果如下: 默认构造函数1 默认构造函数2 默认构造函数3 默认构造函数3 默认构造函数3 //================================================ 解析:上⾯的代码中, "TestMy str3=40" 这句为什么是可以的呢? 在C++中, 如果构造函数只有⼀个参数时, 那么在编译的时候就会有⼀个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象. 也就是说 "TestMy str3=40" 这段代码, 编译器⾃动将整型转换为TestMy 类对象, 实际上等同于下⾯的操作: TestMy str3(40); 或 TestMy temp(40); TestMy str3 = temp; 但是上⾯的代码容易给⼈易解,是会str3开辟个40个char类型⼤⼩的空间,还是说将赋值字符串为“40”,所以上⾯为了解决这种误解,就得加上explicit这个关键字。
C++66个关键字的中文含义
C++66个关键字的中文含义1.asm(汇编),用法如下:asm (指令字符串);允许在C++程序中嵌入汇编代码。
2. auto(自动,automatic)是存储类型标识符,表明变量“自动”具有本地范围,块范围的变量声明(如for循环体内的变量声明)默认为auto存储类型。
3. bool(布尔)类型,C++中的基本数据结构,其值可选为true (真)或者false(假)。
C++中的bool类型可以和int混用,具体来说就是0代表false,非0代表true。
bool类型常用于条件判断和函数返回值。
4. break(中断、跳出),用在switch语句或者循环语句中。
程序遇到break后,即跳过该程序段,继续后面的语句执行。
5. case用于switch语句中,用于判断不同的条件类型。
6. catch catch和try语句一起用于异常处理。
7. char char(字符,character)类型,C++中的基本数据结构,其值一般为0~255的int。
这256个字符对应着256个ASCII码。
char类型的数据需要用单引号’’括起来。
8. class class(类)是C++面向对象设计的基础。
使用class关键字声明一个类。
9. const const(常量的,constant)所修饰的对象或变量不能被改变,修饰函数时,该函数不能改变在该函数外面声明的变量也不能调用任何非const函数。
在函数的声明与定义时都要加上const,放在函数参数列表的最后一个括号后。
在C++中,用const声明一个变量,意味着该变量就是一个带类型的常量,可以代替#define,且比#define多一个类型信息,且它执行内链接,可放在头文件中声明;但在C中,其声明则必须放在源文件(即.C文件)中,在C中const 声明一个变量,除了不能改变其值外,它仍是一具变量。
10. const_cast用法:const_cast (expression)该运算符用来修改类型的const或volatile属性。
C++ 中explicit 关键字的作用
C++ 中explicit 关键字的作用在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换。
explicit使用注意事项:explicit 关键字只能用于类内部的构造函数声明上,explicit 关键字作用于单个参数的构造函数。
在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换。
在C++中,如果一个类有只有一个参数的构造函数,C++允许一种特殊的声明类变量的方式。
在这种情况下,可以直接将一个对应于构造函数参数类型的数据直接赋值给类变量,编译器在编译时会自动进行类型转换,将对应于构造函数参数类型的数据转换为类的对象。
如果在构造函数前加上explicit修饰词,则会禁止这种自动转换,在这种情况下,即使将对应于构造函数参数类型的数据直接赋值给类变量,编译器也会报错。
下面以具体实例来说明。
建立people.cpp 文件,然后输入下列内容:class People{public:int age;People (int a){age=a;}};void foo ( void ){People p1(10);//方式一People* p_p2=new People(10); //方式二People p3=10; //方式三}这段C++程序定义了一个类people,包含一个构造函数,这个构造函数只包含一个整形参数a,可用于在构造类时初始化age变量。
然后定义了一个函数foo,在这个函数中我们用三种方式分别创建了三个10岁的“人”。
第一种是最一般的类变量声明方式。
第二种方式其实是声明了一个people类的指针变量,然后在堆中动态创建了一个people实例,并把这个实例的地址赋值给了p_p2.第三种方式就是我们所说的特殊方式,为什么说特殊呢?我们都知道,C/C++是一种强类型语言,不同的数据类型是不能随意转换的,如果要进行类型转换,必须进行显式强制类型转换,而这里,没有进行任何显式的转换,直接将一个整型数据赋值给了类变量p3.因此,可以说,这里进行了一次隐式类型转换,编译器自动将对应于构造函数参数类型的数据转换为了该类的对象,因此方式三经编译器自动转换后和方式一最终的实现方式是一样的。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
谈谈explicit关键字
2004-08-19 20:35 16677人阅读评论(7) 收藏举报
今天看到公司的代码内有大量的explicit关键字,但是老版的MSDN内例子并不完善,实在是不明白,最终从网上一篇文章内找到了答案:原来explicit是为了防止隐式使用拷贝构造函数的.以下附上从新版MSDN中找到的例子和网上那篇文章:
// Copy From MSDN
This keyword is a declaration specifier that can only be applied to in-class constructor declarations. An explicit constructor cannot take part in implicit conversions. It can only be used to explicitly construct an object.
The following program will fail to compile because of the explicit keyword. To resolve the error, remove the explicit keywords and adjust the code in g.
// spec1_explicit.cpp
// compile with: /EHsc
#include
class C
{
public:
int i;
explicit C(const C&) // an explicit copy constructor
{
printf("/nin the copy constructor");
}
explicit C(int i ) // an explicit constructor
{
printf("/nin the constructor");
}
C()
{
i = 0;
}
};
class C2
{
public:
int i;
explicit C2(int i ) // an explicit constructor
{
}
};
C f(C c)
{ // C2558
c.i = 2;
return c; // first call to copy constructor
}
void f2(C2)
{
}
void g(int i)
{
f2(i); // C2558
// try the following line instead
// f2(C2(i));
}
int main()
{
C c, d;
d = f(c); // c is copied
}
Note explicit on a constructor with multiple arguments has no effect, since
such constructors cannot take part in implicit conversions. However, for the
purpose of implicit conversion, explicit will have an effect if a constructor has
multiple arguments and all but one of the arguments has a default value.
// Copy From Internet Article
Pointer
不看书不知道自己的C++有多差T_T,看到explicit 时遇到一个问题。
请看下面一段程序:class A{
public:
A(int i) : m_i(i){}
int m_i;
};
int main(){
A a = 0;
a = 10; // 这里是什么操作?
}
这个操作产生了一个临时对象。
我怀疑是默认赋值运算符“A &operator = (int i){}”,于是重载了一下该运算符,结果确实运行到重载的运算符函数里了,那么临时对象又是如何产生的呢?
难道默认的赋值运算符是这样操作的?
A &operator = (int i){
A a(i);
return a;
}
这让我想起了类似的函数操作:
void fn(A a){
// ...
}
这里可以直接写fn(10);也是产生了一个临时对象。
难道真的是这样吗?忘解惑。
alexeyomux
老兄你用的是哪个编译器?在我印象之中,好像标准C++并不会给出operator =啊。
等我去试一试。
gongminmin
当然会有默认的operator=了
按照c++标准,编译器会生成五个默认成员函数:
默认构造函数
拷贝构造函数
析构函数
operator=
operator&
千里马肝
class A
{
public:
A(int i) : m_i(i){}
int m_i;
};
分别说说吧:
1. A a = 0;
首先, compiler认为这样写是不符合规矩的, 因为A = A才是正常行为。
但是她并不放弃, 通过搜索, 发现A可以根据一个int构造, 同时这个A(int i)没有用explicit修饰过。
那么A a = 0; 这样的一句话随即转变成:
A tmp(0);
A a = tmp;
需要说明的是, A a = tmp是调用的copy ctor, 虽然class A中并没有, 但是通常不写copy ctor的话,
compiler都会生成一个memberwise assignment操作性质的ctor, 底层实现通常会以memcpy进行。
2. a = 10;
首先, 这样同ctor的情况一样, compiler无法直接进行操作。
类推, 等同于代码:
A tmp(10);
a = tmp;
需要注意的是, a = tmp是调用的assignment操作, 同ctor一样,我们自己不写, 编译器同样进行
memberwise assignment操作。
3. fn(A a)
同样, fn(10)也是不对的, 但是"按照惯例", 呵呵, 会有:
A tmp(10);
fn(tmp);
另外, 为你解惑:
copy ctor的写法只能是T::T(const T &);
而assignment的写法可以多变, 即任意. 以T为例,
可以有
T &operator = (int n);
也可有
T &operator = (const char *);
当然, 你要确认如此的定义是对T而言有意义.
然后, 上述a = tmp, 即调用的默认的、标准的、自动生成的T &operator = (const T &). 开销是会有一个临时的A tmp生成, 然后memcpy.
但如果你自已写了T &operator = (int n), 那么a = 10即意味着a.m_i = 10.
当然, 以开销而言要视你的T &operator = (int n)是否为inline了.
对于explicit, 当修饰explicit A(int i) : m_i(i){}, 那么即告诉compiler不要在私底下做那么多的转换动作.
而且自动生成如A tmp(0)这样的东西是我们不想要的, 因为某些情况下自动转换这种行为是错误的.
最后, 相关此类问题, 还有一个话题, 即class A可以有operator int(), 会在fn(int n){}
A a(3);
fn(a)
起到魔术般的作用. 关于这个, 留给你自己看看书吧:)
最后,祝学习C++的路上一帆风顺。
Good luck~。