首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++ - 我们为什么要在这个构造函数中使用explicit?

在C++中,explicit关键字用于修饰单参数构造函数,它的作用是防止隐式类型转换。当一个构造函数被声明为explicit时,它将只能被用于显式地创建对象,而不能被用于隐式地进行类型转换。

为什么要在构造函数中使用explicit呢?主要有以下几个原因:

  1. 防止隐式类型转换:使用explicit关键字可以防止编译器进行隐式类型转换,避免了可能的错误和意外行为。这样可以提高代码的可读性和可维护性。
  2. 明确代码意图:使用explicit关键字可以明确地表达代码的意图,告诉其他开发者这个构造函数只能被显式调用,不允许隐式类型转换。这样可以减少代码的歧义性,提高代码的可理解性。
  3. 避免不必要的对象创建:有时候,隐式类型转换会导致不必要的临时对象的创建,造成性能上的损失。使用explicit关键字可以避免这种情况的发生,提高代码的执行效率。

在实际应用中,我们可以在需要明确禁止隐式类型转换的情况下使用explicit关键字。例如,当一个类的构造函数只接受一个参数,并且不希望这个参数被隐式转换为该类的对象时,可以使用explicit关键字修饰该构造函数。

腾讯云相关产品和产品介绍链接地址:

暂无相关产品和链接地址。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++要在构造函数和析构函数调用虚函数

但是为什么构造函数调用虚函数,实际上没有发生动态联编呢? 1. 不要在构造函数调用虚函数的原因 第一个原因,在概念上,构造函数的工作是为对象进行初始化。...当创建某个派生类的对象时,如果在它的基类的构造函数调用虚函数,那么此时派生类的构造函数并未执行,所调用的函数可能操作还没有被初始化的成员,浙江导致灾难的发生。...在Visual C++,包含虚函数的类对象的虚指针被安排在对象的起始地址处,并且虚函数表(vtable)的地址是由构造函数写入虚指针的。...2.不要在析构函数调用虚函数的原因 同样的,在析构函数调用虚函数函数的入口地址也是在编译时静态决定的。也就是说,实现的是实调用而非虚调用。 考察如下例子。...从概念上说,析构函数是用来销毁一个对象的,在销毁一个对象时,先调用该对象所属类的析构函数,然后再调用其基类的析构函数,所以,在调用基类的析构函数时,派生类对象的“善后”工作已经完成了,这个时候再调用在派生类定义的函数版本已经没有意义了

2.8K30

C++编程经验(4):不要在构造函数和析构函数使用函数

这个事情呢,其实我们平时也不会去做的,对吧。 当然要是做了的话,那也可以做好某些天连夜加班的准备。...---- 构造函数调用虚函数 首先构造函数不能调用虚函数,不是说语法不允许,最重要的原因在于,当有继承的时候,父类会调用到子类的函数,但是此时子类并没有初始化,会导致数据错误,就这一点足已让你不能在构造函数调用虚函数...在基类的构造过程,虚函数调用从不会被传递到派生类。代之的是,派生类对象表现出来的行为好象其本身就是基类型。不规范地说,在基类的构造过程,虚函数并没有被"构造"。...对于这个问题,看到一个很nice的说法:在一些平台正常,在另一些平台未必正常。今天正常,以后未必正常。 ---- 析构函数调用虚函数 在对象的析构期间,存在与上面同样的逻辑。...一旦进入到基类的析构器,该对象即变为一个基类对象,C++各个部分(虚函数,dynamic_cast运算符等等)都这样处理。

1K30

最全面的c++类的构造函数高级使用方法及禁忌

说明一下,我用的是gcc7.1.0编译器,标准库源代码也是这个版本的。 本篇文章讲解c++构造函数的高级用法以及特殊使用情况。 1....,我们执行一下程序,结果如下: call constructors throw something 可以看到没有执行析构函数,那如果构造函数在申请动态内存以后抛出异常,就会出现内存泄露的问题,那么为什么没有执行析构函数呢...实际上,我们这里首先应该思考一下初始化列表和赋值有什么区别,初始化列表其实相当于调用一次构造函数,而赋值呢,是首先调用一次构造函数,然后再调用赋值函数,相当于先声明,然后又定义一次,但我们初次接触c++...以上三种情况都必须使用初始化列表而不能在构造函数中进行赋值。 7....什么构造函数会在main函数之前执行 想当年面试的时候我想破头都想不出来这个问题,因为main函数是程序入口嘛,但其实这个问题很简单,根据程序的执行规则,在main函数之前,会先处理全局变量和局部静态变量

1.6K30

c++explicit和mutable关键字探究

1. explicit关键字 在写c++标准输入输出相关文章,查看iostream实现代码的时候,经常看到构造函数前面带有explicit关键字,那么它到底有什么作用呢。...explicit关键字,那么可以直接使用class Base base = 5;来给成员变量赋值,这也就算了,就当他是在构造了,但是到了base = 6这一行代码,就很离谱了,没有调用任何set函数,直接就改变了私有成员的值...但如果在构造函数前面加一个explicit关键字,那么代码就不能再这样写啦,编译会报错,如下: //构造函数前面加explicit explicit Base(int p_a){ a = p_a;}...那么为什么explicit可以起到这个作用呢,在没有声明该关键字之前,编译器根据当前的定义和构造函数,在编译的时候做了一个隐式的类型转换,但是当编译器发现了explicit这个关键字之后,就不再做这个隐式转换...2. mutable关键字 mutable用于类的非静态和非常量数据成员,一般类的成员函数被声明为const,就表示不会修改类的数据成员,但如果要在常成员函数修改类的非静态和非常量数据成员,则可以使用

25320

C++核心准则C.50:如果在构造过程需要“虚行为”,使用工厂函数

C.50: Use a factory function if you need "virtual behavior" during initialization C.50:如果在构造过程需要“虚行为...”,使用工厂函数 Reason(原因) If the state of a base class object must depend on the state of a derived part...如果基类对象的状态必须依赖对象的派生部分,我们需要使用函数(或等价物)以便尽量压缩没有完美构造完成的对象被错误使用的时间窗口。...然而,如果工厂的作者知道返回对象的所有的用法都是共享方式,也可以返回shared_ptr,这样在函数体内部可以使用make_shared节约一次内存分配。...通过要求一个保护的令牌保证构造函数不能被公开调用,这样我们就避免了不完全构造的对象流出。由于提供了一个工厂方法create(),(自由存储上的)构造过程可以便利地实施。

60230

c++ explicit 关键字

C++, 一个参数的构造函数(或者除了第一个参数外其余参数都有默认值的多参构造函数), 承担了两个角色。 1 是个构造器 ,2 是个默认且隐含的类型转换操作符。...所以, 有时候在我们写下如 AAA = XXX, 这样的代码, 且恰好XXX的类型正好是AAA单参数构造器的参数类型, 这时候编译器就自动调用这个构造器, 创建一个AAA的对象。...这时候就要在这个构造器前面加上explicit修饰, 指定这个构造器只能被明确的调用,使用, 不能作为类型转换操作符被隐含的使用。 呵呵, 看来还是光明正大些比较好。...explicit构造函数的作用 解析: explicit构造函数是用来防止隐式转换的。...而Test2的构造函数被声明为explicit(显式),这表示不能通过隐式转换来调用这个构造函数,因此代码18行会出现编译错误。 普通构造函数能够被隐式调用。

97230

c++】类和对象(六)深入了解隐式类型转换

那么,为什么使用初始化列表呢?...在C++,如果一个类的构造函数只需要一个参数(或所有参数除了第一个外都有默认值),那么这个构造函数允许从构造函数参数类型到类类型的隐式转换。...虽然看起来像是将整数2赋值给cc2,实际上C++编译器解释为使用2作为参数调用C类的构造函数来初始化cc2。这是因为C(int x)构造函数允许从int到C的隐式转换。...接下来,我们将通过详细说明来解释复制初始化的概念,以及为什么在某些情况下可以通过直接赋值的方式来初始化对象 复制初始化的基本概念 复制初始化通常发生在使用=操作符进行对象初始化的场景。...: class Stack { public: void Push(const C& c) { // } }; 比如我们要在这个容器压入c类型的对象有两种方式: Stack st; C

11810

认真理一理C++构造函数

如何使用构造函数 什么是委托构造函数? 如何禁止拷贝形式的初始化? 前言 我们在C语言中使用堆栈的变量时,常常需要给它赋初始值,用于避免使用到了不可预知的值。...同样的,在C++也需要有这样的动作,只是由于C++的对象可能比基本数据要复杂得多,因此使用了一系列的函数来完成这件事。这些函数就是构造函数。那么构造函数到底是怎样,又该如何使用呢?...另外,从这个例子我们也可以看到,由于Foo已经定义了自己的构造函数,因此编译器不会为它生成默认的构造函数。 如何解决呢?...只需要在Foo类增加这么一句就可以使用默认构造函数了: Foo()= default; 构造函数初始值 为了在构造函数给成员赋初始值,可以用下面的方式: //公众号【编程珠玑】,博客 https:...使用构造函数 在前面我们已经看到了构造函数使用方式。

53420

C++修炼之路】5. 类和对象(下)

对于B类内部成员的初始化,我们构造函数是行不通的: 自定义类型成员没有构造函数 引用和const 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化...explicit修饰单参数的构造函数之后,我们发现其就不支持隐式类型转换。...事实上这个在后面类似于string等容器将会介绍(上面演示的不加explicit修饰的构造函数在需要隐式类型转换时都是构造+拷贝构造,但通过string等容器可以直接拷贝构造)在这里只需要知道:explicit...:int A::N = 0;;第二个问题,N实际上作为私有值,我们不能直接的访问他,因此我们要在定义一个函数返回N。...优化场景2: 对于优化前,我们知道,这是aa1先构造之后再传入函数引起参数拷贝构造,但优化后可以看出通过匿名对象不创建对象这个特性,我们就可以将传参的拷贝构造这一步省去,只有构造匿名对象这一步。

35000

【重学C++】03 | 手撸C++智能指针实战教程

另外,有一点值得注意,smart_ptr的构造函数使用explicitexplicit关键字主要用于防止隐式的类型转换。代码,如果原生指针隐式地转换为智能指针类型可能会导致一些潜在的问题。...当前我们没有为smart_ptr自定义拷贝构造函数/移动构造函数C++会为smart_ptr生成默认的拷贝/移动构造函数。默认的拷贝/移动构造函数逻辑很简单:把每个成员变量拷贝/移动到目标对象。...在移动构造函数我们先是接管了other.ptr_指向的资源对象,然后把other的ptr_置为nullptr,这样在other析构时就不会错误释放资源内存。...在赋值函数我们使用std::swap交换了 rhs.ptr_和this->ptr_,注意,这里不能简单的将rhs.ptr_设置为nullptr,因为this->ptr_可能有指向一个堆对象,该对象需要转给...下面详细展开各个函数的实现。为了避免对count_的重复删除,我们保持:只有当ptr_ != nullptr时,才对count_进行赋值。构造函数同样的,使用explicit避免隐式转换。

19200

【专业技术】C++里面重要的几个关键字的用法

如果一个类的成员函数被声明为const类型,表示该函数不会改变对象的状态,也就是该函数不会修改类的非静态数据成员.但是有些时候需要在该类函数对类的数据成员进行赋值.这个时候就需要用到mutable关键字了...编译上面的代码会出现 error C2166: l-value specifies const object的错误说明在const类型的函数改变了类的非静态数据成员.这个时候需要使用mutable来修饰一下要在...我们先来实现一个简单的函数,来观察一下由编译器产生出来的汇编代码的不足之处,并观察volatile关键字如何修正这个不足之处。...explicit关键字 我们在编写应用程序的时候explicit关键字基本上是很少使用,它的作用是"禁止单参数构造函数"被用于自动型别转换,其中比较典型的例子就是容器类型,在这种类型的构造函数你可以将初始长度作为参数传递给构造函数...3arr = 40; 此时,C++的自动型别转换会把40转换成拥有40个元素的Array,并且指派给arr变量,这个结果根本就不是我们想要的结果.如果我们构造函数声明为explicit,上面的赋值操作就会导致编译器报错

80770

C++初阶学习第五弹——类与对象(下)——类与对象的收官战

前言: 在前面我们已经学习了C++类与对象的关键操作——默认成员函数,今天我们对之前的内容进行一些补充,同时再来学习几个新的知识点Static成员、友元和内部类 一、构造函数进阶 1.1 构造函数的赋值化...单参构造函数,没有使用explicit修饰,具有类型转换作用 // explicit修饰构造函数,禁止类型转换---explicit去掉之后,代码可以通过编译 explicit Date(int year...虽然有多个参数,但是创建对象时后两个参数可以不传递,没有使用explicit修饰,具有类型转 换作用 // explicit修饰构造函数,禁止类型转换 explicit Date(int year...用static修饰的成员变量就是类的静态成员变量,用static修饰的成员函数就是静态成员函数 我们需要注意的是静态成员变量一定要在类外进行初始化 class A { private: static...,所以我们平时要尽量减少使用友元 友元有两种:友元类和友元函数 3.1 友元函数 对于一些函数而言,并不适合将它封装在类,比如operator<<流输出函数 我们一般是这样用这个函数的: int

7610

openFoam源码C++

openFoam源码涉及到的c++思想有很多,因为在计算流体力学,域的创建尤为重要,我们可以在域中存储我们想要的物理变量如速度、压力等等。...首先:有一个宏观上的思维,我们用的大多数域对应的C++类是GeometricField,这个类里面包含了很多信息,但他的Base类其实是Field这个类,可以用下图来表示这个关系: ?...,其中比较有意思的是: explicit Field(const label); 这里explict的解释我总结如下: C++explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的...A = 10;但是这个10并不代表size,不伦不类 接下来,该类还使用了一些复制构造函数,这都是我们平常开发不经常使用的操作: Field(const Field&);...在.C文件我们也可以看见一些有意思的写法,比如说模板构造函数,成员变量的直接初始化等等: const char* const Foam::Field::typeName("Field")

88630

C++ explicit关键字详解

C++ explicit关键字详解 首先, C++explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的,跟它相对应的另一个关键字是implicit...我们来看下面的例子: class CxString // 没有使用explicit关键字的类声明, 即默认为隐式声明 { public: char *_pstr; int...在C++, 如果的构造函数只有一个参数时, 那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象....我们把上面的代码修改一下, 如下: class CxString // 使用关键字explicit的类声明, 显示转换 { public: char *_pstr; int...关键字依然有效, 此时, 当调用构造函数时只传入一个参数, 等效于只有一个参数的类构造函数, 例子如下: class CxString // 使用关键字explicit声明 { public

6.5K40

【重学 C++】06 | C++该不该使用 explicit

文章首发【重学 C++】06 | C++该不该使用 explicit引言大家好,我是只讲技术干货的会玩code,今天是【重学C++】的第六讲,在 C++explicit关键字作用于类的构造函数或类型转换操作符...今天,我们来聊聊到底该不该使用explicitexplicit的作用在C++,默认允许隐式转换,隐式类型转换是指在表达式自动进行的类型转换,无需显式地指定转换操作。...这种错误比较隐晦,在编译过程也不会有任何warning提示。对象被错误回收经典例子就是智能指针了,我们在《03 |手撸C++智能指针实战教程》一节也提到过,下面我们再来回顾一下。...隐式转换合理使用场景拷贝构造函数和移动构造函数对于拷贝构造函数和移动构造函数我们通常希望它们能够在需要时自动调用,以便进行对象的拷贝和移动操作。...在拷贝构造函数和移动构造函数,不推荐使用 explicit,以便编译器可以自动调用这些构造函数

20600

C++的explicitkeyword

C++程序中非常少有人去使用explicitkeyword,不可否认,在平时的实践确实非常少能用的上。再说C++的功能强大,往往一个问题能够利用好几种C++特性去解决。...但略微留心一下就会发现现有的MFC库或者C++标准库的相关类声明explicit出现的频率是非常高的。...了解explicitkeyword的功能及其使用对于我们阅读使用库是非常有帮助的,并且在编写自己的代码时也能够尝试使用。既然C++语言提供这样的特性,我想在有些时候这样的特性将会非常实用。...CExample objFour = 12; //运行了隐式转换,等价于CExample temp(12);objFour(temp);注意这个地方调用了 //编译器为我们提供的默认复制构造函数...通过将构造函数声明为explicit(显式)的方式能够抑制隐式转换。也就是说,explicit构造函数必须显式调用。

44530

【细品C++】类和对象的一些细节(初始化列表、友元、static成员等)

而你想自己写一个构造函数处理这个问题时,发现如果你想解决这个问题,你就必须手动调用这个自定义类型成员的构造函数,而你想调用这个构造函数就必须要在这个自定义类型成员定义初始化时调用。...隐式类型转换构造explicit关键字 构造函数不仅可以构造与初始化,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用。...,没有使用explicit修饰,具有类型转换作用 //date(int year) //explicit修饰构造函数,禁止类型转换——explicit去掉之后,代码可以通过编译 explicit...,有时候我们并不希望这样,并且这样代码可读性也不是很好,那就使用explicit修饰构造函数,禁止构造函数的隐式转换。...但是实际上我们正常使用cout是左操作数,也就是需要作为重载函数的第一个形参,所以需要重载成全局函数,但是这又会导致类外没办法访问成员,此时就需要友元来解决。operator>>同理。

39720

C++】类和对象之初始化列表与static成员

前言 在前面的博客已经分享有关构造函数C++构造函数和析构函数详解,这次又再一次提到构造函数,一起来看看。 2....(2)const成员变量 (3)自定义类型成员(且该类没有默认构造函数时) 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。...不会,2构造一个临时对象,再拷贝构造 -> 编译器优化了,同一个表达式连续步骤的构造,一般会被合二为一 这个代码为什么可以? 类型转换会产生临时变量。...关键字 explicit修饰构造函数,禁止类型转换 虽然有多个参数,但是创建对象时后两个参数可以不传递,没有使用explicit修饰,具 有类型转换作用 用explicit修饰构造函数,将会禁止构造函数的隐式转换...静态成员变量一定要在类外进行初始化。 面试题:实现一个类,计算程序创建出了多少个类对象。 就是统计构造构造函数调用了多少次。

11010

c++类和对象新手保姆级上手教学(下)

初始化列表: 在中篇我们提到了构造函数的功能是初始化变量,接下来讲到的初始化列表也有同样的功能。...用法: 初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号的初始值或表达式 既然它的功能和构造函数一样,那为什么要有初始化列表呢?...当然是为做到构造函数做不到的事情,比如: 我们有一个const的变量,那么就代表它在被定义的时候就必须被初始化,如果我们构造函数,就会报错,如下: 而初始化列表就可以很好地解决这个问题: 如果成员变量有引用...explicit关键字: 在C++98,单参数构造函数,支持隐式类型转换,比如: 这样写代码会方便一点,那么多参数的构造函数有没有这个隐式类型转换呢?...C++11,支持了多参数的构造函数隐式类型转换: 那么有没有什么办法让这个隐式类型转换不发生呢?很简单,在构造函数前,加上关键字explicit即可: 可以看到加上后再使用隐式类型转换会直接报错。

7410
领券