C++中explicit关键字的作用
C++中explicit关键字的作用
explicit用来防止由构造函数定义的隐式转换。
要明白它的作用,首先要了解隐式转换:可以用单个实参来调用的构造函数定义了从形参类型到该类
类型的一个隐式转换。
例如:
classthings
{
public:
things(conststd::string&name=""):
m_name(name),height(0),weight(10){}
intCompareTo(constthings&other);
std::stringm_name;
intheight;
intweight;
};
这里things的构造函数可以只用一个实参完成初始化。所以可以进行一个隐式转换,像下面这样:
thingsa;
................//在这里被初始化并使用。
std::stringnm="book_1";//由于可以隐式转换,所以可以下面这样使用
intresult=a.CompareTo(nm);
这段程序使用一个string类型对象作为实参传给things的CompareTo函数。这个函数本来是
需要一个tings对象作为实参。现在编译器使用stringnm来构造并初始化一个things对象,新生成的临时的things对象被传递给CompareTo函数,并在离开这段函数后被析
构。
这种行为的正确与否取决于业务需要。假如你只是想测试一下a的重量与10的大小之比,这么
做也许是方便的。但是假如在CompareTo函数中还涉及到了要除以初始化为0的height属性,那
么这么做可能就是错误的。需要在构造tings之后更改height属性不为0。所以要限制这种隐式类
型转换。
那么这时候就可以通过将构造函数声明为explicit,来防止隐式类型转换。
explicit关键字只能用于类内部的构造函数声明上,而不能用在类外部的函数定义上。现在
things类像这样:
classthings
{public:
explicitthings(conststd::string&name=""):
m_name(name),height(0),weight(0){}
intCompareTo(constthings&other);
std::stringm_name;intheight;intweight;
};
这时再进行编译,在vs2008上会提示:没有可用于执行该转换的用户定义的转换运算符,或者
无法调用该运算符。
这时你仍然可以通过显示使用构造函数完成上面的类型转换:
thingsa;
................//在这里被初始化并使用。std::stringnm="book_1";//显示使用构造
函数intresult=a.CompareTo(things(nm));
google的c++规范中提到explicit的优点是可以避免不合时宜的类型变换,缺点无。所以
google约定所有单参数的构造函数都必须是显示的,只有极少数情况下拷贝构造函数可以不声明称
explicit。例如作为其他类的透明包装器的类。effectivec++中说:被声明为explicit的构造函数通常比其non-explicit兄弟更受欢迎。因为
它们禁止编译器执行非预期(往往也不被期望)的类型转换。除非我有一个好理由允许构造函数被用
于隐式类型转换,否则我会把它声明为explicit。我鼓励你遵循相同的政策。
explicit和implicit的含义
explicit 和 implicit 属于转换运算符,如用这两者可以让我们自定义的类型支持相互交换
explicti 表示显式转换,如从 A -> B 必须进行强制类型转换(B=(B)A)
implicit 表示隐式转换,如从 B -> A 只需直接赋值(A=B)
隐式转换可以让我们的代码看上去更漂亮、更简洁易懂,所以最好多使用
implicit 运算符。不过!如果对象本身在转换时会损失一些信息(如精度),那么我们只能使用 explicit 运算符,以便在编译期就能警告客户调用端
示例:
using System;
using System.Collections.Generic;
using System.Text;
namespace Example23
{
class Program
{
//本例灵感来源于大话西游经典台词“神仙?妖怪?”–主要是我实在想不出什么好例子了
class Immortal
{
public string name;
public Immortal(string Name)
{
name=Name;
}
public static implicit operator Monster(Immortal value)
{
return new Monster( + “:神仙变妖怪?偷偷下凡即可。。。”);
}
}
class Monster
{
public string name;
public Monster(string Name)
{
name=Name;
}
public static explicit operator Immortal(Monster value)
{
return new Immortal( + “:妖怪想当神仙?再去修炼五百年!”);
c语言extern和static关键字的用法
第 1 页 共 2 页 c语言extern和static关键字的用法
C语言是一种广泛使用的编程语言,它具有简洁、灵活和易于学习的特点。在C语言中,extern和static是两个非常重要的关键字,它们在变量声明和存储方面起着关键作用。
一、extern关键字
extern关键字用于声明一个变量或函数是在其他文件中定义的。它告诉编译器在其他地方查找变量或函数的定义。extern关键字在变量或函数的使用前声明时使用。
例如,假设我们有一个在其他文件中定义的变量x,我们可以这样使用extern关键字:
```c
extern int x;
```
上述代码将允许我们在当前文件中使用变量x。然而,如果x在其他文件中并未定义,那么这将导致编译错误。
二、static关键字
static关键字用于声明一个变量或函数是静态的。静态变量和函数在编译时分配内存,并且只分配一次。这意味着它们在程序的生命周期内一直存在,并且在程序运行期间不会消失。静态变量和函数只在其所在的编译单元(文件)中可见。
例如,我们可以这样使用static关键字来声明一个静态变量:
```c
static int y;
``` 第 2 页 共 2 页 上述代码将声明一个名为y的静态整数变量,该变量只在其所在的编译单元中可见。
在C语言中,extern和static可以结合使用,以实现变量的作用域限制和生命周期控制。例如,我们可以使用extern声明一个在另一个文件中定义的静态变量:
```c
static int z; // 声明一个静态变量z,只在其所在的编译单元中可见
extern static int x; // 声明一个在另一个文件中定义的静态变量x,可以在当前文件中使用
```
需要注意的是,如果我们在当前文件中多次使用extern关键字来引用同一个静态变量,编译器会认为这是重复声明同一个变量,因此会导致编译错误。为了解决这个问题,我们需要在不同的文件中有独立的定义和声明。
c语言中external,static关键字用法
c语⾔中external,static关键字⽤法
static⽤法:
在C中,static主要定义全局静态变量、定义局部静态变量、定义静态函数。
1、定义全局静态变量:在全局变量前⾯加上关键字static,该全局变量变成了全局静态变量。全局静态变量有以下特点。a.在全局区分配内存。b.如果没有初始化,其默认值为0.c.该变量在本⽂件内从定义开始到⽂件结束可见。
2、定义局部静态变量:在局部变量前⾯加上关键字static,其特点如下:a.该变量在全局数据区分配内存。b.它始终驻留在全局数据区,直到程序运⾏结束。c. 其作⽤域为局部作⽤域,当定义它的函数或语句块结束时,其作⽤域随之结束。
3、定义静态函数:在函数返回类型前加上static关键字,函数即被定义为静态函数,其特点如下:
a.静态函数只能在本源⽂件中使⽤
b.在⽂件作⽤域中声明的inline函数默认为static类型
总结:⽤static定义的全局和局部静态变量的区别是,全局的静态变量的作⽤域和可见域都是从⽂件的定义开始到整个⽂件结束;⽽局部的静态变量可见域是从⽂件的定义开始到整个⽂件结束,作⽤域是从该语句块的定义开始到该语句块结束
extern的⽤法:
1、声明⼀个全局(外部)变量
当⽤extern声明⼀个全局变量的时候,⾸先应明确⼀点:extern的作⽤范围是整个⼯程,也就是说当我们在.h⽂件中写了extern int a;链接的时候链接器会去其他的.c⽂件中找有没有int a的定义,如果没有,链接报错;当extern int a;写在.c⽂件中时,链接器会在这个.c⽂件该声明语句之后找有没有int a的定义,然后去其他的.cpp⽂件中找,如果都找不到,链接报错。值得注意的⼀点:当extern语句出现在头⽂件中时,不要将声明和定义在⼀条语句中给出,也就是不要在头⽂件中写类似于这样的语句:
extern int a = 1;这种写法,在gcc编译时会给出⼀个警告:warning: 'a' initialized and declared 'extern'
C语言32以及C++63个关键字及其含义
C语言32个关键字及其含义
auto:自动变量用关键字auto作存储类别的声明。(可以省略,不写则隐含确定为“自动存储类别”)
break:不能用于循环语句和switch语句之外的任何其他语句中。作用为结束循环。
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:无返回
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语句一起用于异常处理。
explicit用法
- 1 - explicit用法
Explicit是一个英文单词,它的意思是“明确的”、“清晰的”、“明文规定的”。在不同的语境下,explicit的用法也不尽相同。以下是一些常见的用法:
1. Explicit language:这是指带有粗俗、露骨、不雅等特点的语言。例如,有些电影或歌曲会含有explicit language的警告。
2. Explicit content:这是指含有成人内容、暴力、色情等敏感内容的媒体作品,例如电影、电视剧、小说、音乐等。一些网站或平台会标注内容为explicit,以便用户自行选择是否查看。
3. Explicit instruction:这是指明确的指示或规定。例如,老师在讲解问题时给出的步骤、法律文件中的具体规定等都可以称作explicit instruction。
4. Explicit memory:这是指明确的记忆,即通过有意识的努力所产生的记忆。例如,学习时专门记忆某个知识点,或者有意识地练习某项技能,都是属于explicit memory的范畴。
5. Explicit function:这是指可以明确表达、定义的函数。在数学领域中,一些函数可以用明确的公式或算法来表示,这些函数就可以被称为explicit function。
总之,explicit这个词在不同的场合中有着不同的含义和用法,需要具体情境去理解。
c++0x
维基百科c++0x
1. 介绍
C++0x(读作see plus plus oh ex)是c++编程语言预计的新标准的一个非正式名称。今后会替换现有的c++标准,(ISO/IEC 14882)的这个1998年发布并在2003年更新的版本。老版本可以通俗的叫做c++98和c++03。新版本会添加一些语言核心内容和扩展c++标准库,将纳入c++技术报告库(C++ Technical Report 1 (TR1) libraries)-很可能不包含特殊的数学函数。目前为止这个标准还未完成,这篇文章可能不能反映出最近的c++0x情况。N3092的这个国际草案标准在2010年的3月被发布了。
ISO/IEC JTC1/SC22/WG21 c++标准委员会的计划是完成投票表决最后的委员会草案在2010年的8月,和在2011年的3月的标准会议上完善最后的国际草案标准。不管怎样,WG21 预计到ISO官方发布标准会经历6个月到1年的时间,到这个标准的发行出版得到2011年末。为了完成日程,委员会决定集中精力解决截至到2006年的问题而忽略新产生的决议。
c++这样的编程语言使用进化的方式改善和发展。在c++发展的过程中用这样的方式必定会引起兼容以前代码的问题。不管怎样,根据Bjarne Stroustrup(C + +语言的创作者和委员会的成员)的公告,新标准将“几乎百分之百的兼容现有的标准C + +".
2. 变更内容简介
内容
1 c++的版本变动即将标准更新
2 扩展C + +的语言核心
3 运行时核心语言的性能增强
3.1右值引用(Rvalue reference)和移动语义(move semantics)
3.2广义常量表达式(Generalized constant expressions)
3.3修改旧数据的简单(plain)定义
4 核心语言生成时的性能增强
构造函数详解,explicit,初始化列表
构造函数详解,explicit,初始化列表
⼀、构造函数
在类中有⼀种特殊的成员函数,它的名字与类名相同,我们在创建类的时候,这个特殊的成员函数就会被系统调⽤。这个成员函数,就
叫“构造函数”。
因为构造函数会被系统⾃动调动,构造函数的⽬的就是初始化类对象的数据成员。
(1)构造函数没有返回值,这是构造函数的特殊之处。
(2)不可以⼿⼯调⽤构造函数,否则编译会出错。
(3)正常情况下,构造函数应该被声明为public,因为创建⼀个对象时,系统要替我们调⽤构造函数,这说明构造函数是⼀个public的成员
类缺省的成员是私有成员,因此对于构造函数我们必须将其声明为public
class Time
{
private:
int Millsecond; // 毫秒
public:
int Hour; // ⼩时
int Minute; // 分钟
int Second; // 秒钟
void initTime(int tmpHour, int tmpMinute ,int tmpSecond)
{
Hour = tmpHour;
Minute = tmpMinute;
Second = tmpSecond;
}
void initMillTime(int mls)
{
Millsecond = mls; // 成员函数可以访问成员变量,不管成员是否私有
}
public:
// 构造函数
Time(int tmpHour, int tmpMinute ,int tmpSecond = 12)
{
Hour = tmpHour;
Minute = tmpMinute;
Second = tmpSecond;
initMillTime(0);
cout << “调⽤了构造函数” <
}
Time() // 不加参数的构造函数
{
Hour = 0;
Minute = 0;
Second = 0;
initMillTime(0);
cout <<”不加参数的构造函数” <
c关键字精选大全
C++关键字大全
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.catchcatch和try语句一起用于异常处理。
7.charchar(字符,character)类型,C++中的基本数据结构,其值一般为0~255的int。这256个字符对应着256个ASCII码。char类型的数据需要用单引号’’括起来。
8.classclass(类)是C++面向对象设计的基础。使用class关键字声明一个类。
9.constconst(常量的,constant)所修饰的对象或变量不能被改变,修饰函数时,该函数不能改变在该函数外面声明的变量也不能调用任何非const函数。在函数的声明与定义时都要加上const,放在函数参数列表的最后一个括号后。
在C++中,用const声明一个变量,意味着该变量就是一个带类型的常量,可以代替#define,且比#define多一个类型信息,且它执行内链接,可放在头文件中声明;但在C中,其声明则必须放在源文件(即.C文件)中,在C中const声明一个变量,除了不能改变其值外,它仍是一具变量
10.const_cast用法:const_cast(expression)该运算符用来修改类型的const或volatile属性。除了const或volatile修饰之外,type_id和expression的类型是一样的。
extern在c语言中是什么意思
extern在c语言中是什么意思
在C语言中,extern关键字主要用于声明一个变量或函数是在其他文件或程序模块中定义的,而不是在当前文件中定义的。这允许程序员在不同的源文件中共享变量和函数。
以下是extern在C语言中的常见用法:
声明外部变量:当你想在一个文件中使用一个在另一个文件中定义的变量时,你需要使用extern来声明该变量。这告诉编译器该变量的定义在其他地方,而不是在当前文件中。
c复制代码
// file1.c
int myGlobalVariable = 10;
// file2.c
extern int myGlobalVariable; // 声明外部变量
int main() {
printf("%d\n", myGlobalVariable); // 输出10
return 0;
} 声明外部函数:当你想在一个文件中调用另一个文件中定义的函数时,你也需要使用extern来声明该函数。
c复制代码
// file1.c
void myFunction() {
printf("This is a function!\n");
}
// file2.c
extern void myFunction(); // 声明外部函数
int main() {
myFunction(); // 调用函数
return 0;
}
需要注意的是,虽然extern关键字用于声明变量或函数,但它本身并不创建或分配任何内存。它只是告诉编译器,这些变量或函数在其他地方已经被定义和分配了。
在实际的项目中,为了提高代码的可读性和可维护性,通常会将全局变量和函数的定义放在一个或多个头文件中,并在需要使用这些变量或函数的源文件中包含这些头文件。这样,你就不需要在每个源文件中都使用extern来声明这些变量或函数了。
[018]C++explicit构造函数
[018]C++explicit构造函数
explicit
[英][ɪkˈsplɪsɪt][美][ɪkˈsplɪsɪt]
adj.明确的,清楚的; 直⾔的; 详述的; 不隐瞒的;
看到上⾯的英⽂解释,我们应该就知道explicit构造函数是什么意思了:显式的构造函数!
⼀、隐式构造函数
如果C++类的构造函数有⼀个参数,那么在编译的时候就会有⼀个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象,如
下⾯所⽰:
class Myclass {
public:
Myclass(int num){};
};
如果我们执⾏这样的操作,就相当于⾃动将整型转换为MyClass类对象
MyClass obj = 10; //ok,convert int to MyClass
它与下⾯的代码相等:
MyClass temp(10);
MyClass obj = temp;
⼆、显⽰构造函数
虽然隐式转换很⽅便,但是在有些时候,我们可能不需要这些隐式转换,⽐如:
1 class Myclass {
2 public:
3 Myclass(int num) { // 输出数字
4 cout << num <
5 }
6 Myclass(const char* p) { // 输出字符
7 cout << *p << endl;
8 }
9 };
如果我们按照下⾯的⽅式来定义:
Myclass obj2(2);
Myclass obj3 = Myclass("b");
这样会各⾃调⽤各⾃的构造函数来进⾏打印,分别输出“2”和“b”。
但是如果我们继续按照隐式转换的⽅式来写:
Myclass obj = 10;
Myclass obj1 = 'a';
虽然都会编译通过,但是会被隐式转换,obj1最后打印输出了b的ASCII码。
为了避免上⾯的情况的错误发⽣,我们可以声明显⽰的转换,使⽤explicit 关键字:
1 class Myclass {
2 public:
3 explicit Myclass(int num) {
