c++中explicit与mutable关键字的深入探究

 更新时间:2021年05月10日 09:29:16   作者:cpp加油站  
这篇文章主要给大家介绍了关于c++中explicit与mutable关键字的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

今天说一说c++里面的两个关键字explicit和mutable。

1. explicit关键字

在写c++标准输入输出相关文章,查看iostream实现代码的时候,经常看到构造函数前面带有explicit关键字,那么它到底有什么作用呢。

explicit用来防止由构造函数定义的隐式转换,先看这样一段代码:

#include <iostream>

class Base
{
private:
    int a;
public:
    Base(int p_a){
		a = p_a;}
    ~Base(){}
	void print()
	{
		std::cout << "a=" << a << std::endl;
	}
};

int main()
{
	Base base = 5;
	base.print();
	base = 6;
	base.print();
	return 0;
}

声明一个只有一个int类型私有成员变量的类,这个时候没有使用explicit关键字,那么可以直接使用class Base base = 5;来给成员变量赋值,这也就算了,就当他是在构造了,但是到了base = 6这一行代码,就很离谱了,没有调用任何set函数,直接就改变了私有成员的值,这就相当于,你自己房子里面放的钱,别人可以隔墙修改你的钱的数量,想想看,你有10000块钱放家里,有个人手指一点,钱变成100了,是不是很可怕。

但如果在构造函数前面加一个explicit关键字,那么代码就不能再这样写啦,编译会报错,如下:

//构造函数前面加explicit
explicit Base(int p_a){
  a = p_a;}

报错内容类似这样的:test.cpp:19:14: error: conversion from 'int' to non-scalar type 'Base' requested,这样就避免了别人隔墙修改你家钱的数量啦。

那么为什么explicit可以起到这个作用呢,在没有声明该关键字之前,编译器根据当前的定义和构造函数,在编译的时候做了一个隐式的类型转换,但是当编译器发现了explicit这个关键字之后,就不再做这个隐式转换,这个时候等号两边的值类型很明显就不一样,当然会报编译错误啦。

总结:explicit告诉别人,不允许隔墙修改我家钱的数量,你要修改的话,必须进到屋子里才行。

2. mutable关键字

mutable用于类的非静态和非常量数据成员,一般类的成员函数被声明为const,就表示不会修改类的数据成员,但如果要在常成员函数中修改类的非静态和非常量数据成员,则可以使用mutable修饰该数据成员,如下:

#include <iostream>

class demo
{
public:
int getCnt() const
{
	m_nCount++;
	return m_nCount;
}

private:
	int m_nCount;
};

int main()
{
	return 0;
}

编译会报错:test.cpp:13: 错误:increment of data-member ‘demo::m_nCount' in read-only structure,但如果改为如下代码:

#include <iostream>

class demo
{
public:
int getCnt() const
{
	m_nCount++;
	return m_nCount;
}

private:
	mutable int m_nCount;
};

int main()
{
	return 0;
}

在int类型前面加一个mutable关键字,编译就通过了。

总结:mutable允许你在一个固定不变的房子里面放置某些可变的物件。

到此这篇关于c++中explicit与mutable关键字的文章就介绍到这了,更多相关c++ explicit与mutable关键字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言详细讲解循环语句的妙用

    C语言详细讲解循环语句的妙用

    C语言循环控制语句是一个基于C语言的编程语句,该语句主要有while循环语句、do-while循环语句和for循环语句来实现循环结构,在循环过程中还有关键字break、continue、do、break控制中断继续与结束等操作
    2022-04-04
  • C++段错误(Segmentation fault)快速定位的解决方法

    C++段错误(Segmentation fault)快速定位的解决方法

    写过C++的朋友都知道,有时候程序编译通过,并不能代表程序就是对的,在linux下做开发时,经常会遇到跑崩溃的情况,但是在终端只会报Segmentation fault,如果工程代码量少,你还能重新debug一下慢慢找,本文给大家介绍了C++段错误的快速定位,需要的朋友可以参考下
    2024-07-07
  • 浅析内存对齐与ANSI C中struct型数据的内存布局

    浅析内存对齐与ANSI C中struct型数据的内存布局

    当在C中定义了一个结构类型时,它的大小是否等于各字段(field)大小之和?编译器将如何在内存中放置这些字段?ANSI C对结构体的内存布局有什么要求?而我们的程序又能否依赖这种布局
    2013-09-09
  • C++深浅拷贝和string类的两种写法详解

    C++深浅拷贝和string类的两种写法详解

    这篇文章主要为大家详细介绍了C++深浅拷贝和string类的两种写法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • 实例讲解C++设计模式编程中State状态模式的运用场景

    实例讲解C++设计模式编程中State状态模式的运用场景

    这篇文章主要介绍了实例讲解C++设计模式编程中State状态模式的运用场景,文章最后的适用性部分则介绍了一些State模式善于处理的情况,需要的朋友可以参考下
    2016-03-03
  • C++11 并发指南之std::thread 详解

    C++11 并发指南之std::thread 详解

    这篇文章主要介绍了C++11 并发指南之std::thread 详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • 简单了解设计模式中的装饰者模式及C++版代码实现

    简单了解设计模式中的装饰者模式及C++版代码实现

    这篇文章主要介绍了简单了解设计模式中的装饰者模式及C++版代码实现,ConcreteComponent的引用(指针)也可以达到修饰的功能,需要的朋友可以参考下
    2016-03-03
  • 解决VC++编译报错error C2248的方案

    解决VC++编译报错error C2248的方案

    这篇文章主要介绍了解决VC++编译报错error C2248的方案的相关资料,需要的朋友可以参考下
    2015-11-11
  • 关于C++中虚拟继承的一些总结分析

    关于C++中虚拟继承的一些总结分析

    虚拟继承在一般的应用中很少用到,所以也往往被忽视,这也主要是因为在C++中,多重继承是不推荐的,也并不常用
    2013-09-09
  • C语言实现电脑关机程序

    C语言实现电脑关机程序

    这篇文章主要为大家详细介绍了C语言实现电脑关机程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02

最新评论