C++ 关键字 explicit, export, mutable
转自
explicit
如果A类有某个构造函数的单个输入参数,是B类(包括基本数据类型)的对象或引用,则C++的编译器会在需要A类形参的函数调用中,自动调用该构造函数,将B类实参隐式地转换为A类实参。
这种自动类型转换的好处是,避免了定义函数的两个重载版本,代价是隐式调用构造函数会增加调用开销,并可能会带来其他问题。
在标准C++中,新增加了关键字explicit(显式/清楚/明确),(只能)用在带单个参数的构造函数前,告诉编译器,不能使用该构造函数进行隐式类型转换。如果确实想转换,则必须采用显式的类型转换方式来进行。从而避免了可能出现的问题和额外的调用开销。
例如:
class One {……};
class Two {
public:
explicit Two (const One& one) {……}
};
void f (Two two) {……}
int main ( ) {
One one;
f (one); // 错误(前面代码中无explicit时正确——调用Two(one)进行隐式类型转换)
f (Two(one)); // 正确——采用了显式类型转换
}
export
为了访问其他编译单元(如另一代码文件)中的变量或对象,对普通类型(包括基本数据类、结构和类),可以利用关键字extern,来使用这些变量或对象时;但是对模板类型,则必须在定义这些模板类对象和模板函数时,使用标准C++新增加的关键字export(导出/出口/输出)。例如:
extern int n;
extern struct Point p;
extern class A a;
export template<class T> class Stack<int> s;
export template<class T> void f (T& t) {……}
一般是在头文件中给出类的定义或全局函数的声明信息,而在代码文件中给出具体的(类成员函数或全局函数的)函数定义。然后在多个用户代码文件中包含该头文件后,就可以使用其中定义或声明的类和函数。头文件中一般不包含变量、结构和类对象的定义,因为这样可能会导致重复定义的编译错误。解决办法是,在某个代码文件中进行定义,在其他用户代码文件中用extern来引用它们。
但是对模板类型,则可以在头文件中,声明模板类和模板函数;在代码文件中,使用关键字export来定义具体的模板类对象和模板函数;然后在其他用户代码文件中,包含声明头文件后,就可以使用该这些对象和函数了。例如:
// out.h:(声明头文件——只包含out函数的声明信息)
template<class T> void out (const T& t);
// out.cpp:(定义代码文件——包含out函数的声明[通过include]和定义等全部信息)
#include <iostream>
#include “out.h”
export template<class T> void out (const T& t) {std::cerr << t;}
//user.cpp:(用户代码文件——包含函数的声明头文件后就可以使用该函数)
#include “out.h”
// 使用out()
说明:VC05目前还不支持export关键字(的编译)。
mutable
在类的常型(const)成员函数中,一般是不让改变类中数据成员的。如果想在常型成员函数中改变类的数据成员,在传统C++中,为达到此目,可采用一种奇怪的方式——先将this指针强制转换成一个本类的指针,然后就可以利用该指针来对类的数据成员进行任意的修改。但是,这种修改是隐藏在成员函数内部的,在类定义(头文件)中根本看不出来,而且它也破坏了设置常型成员函数的本意。
标准C++中新增加了一个关键字mutable(易变/可变/不定/无常的),用在类的数据成员前,明确表示该成员变量可以在常型成员函数中被修改。例如:
class A {
int i;
mutable int j;
public:
void f ( ) const;
};
void A::f ( ) const {
i++; // 错误——常型成员函数不允许改变数据成员的值
((A*)this)->i++; // 可以——已经过时,不被提倡
j++; // 正确——mutable型成员变量
}
C++ 关键字 explicit, export, mutable的更多相关文章
- C++关键字 explicit
C++提供了关键字explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生.声明为explicit的构造函数不能在隐式转换中使用. C++中, 一个参数的构造函数(或者除了第一个参数 ...
- 关键字explicit
今天在<C++ Standard Library>中看到 explicit 的作用,在这里做一下笔记,以备下次再次忘记该关键字的作用. By using the keyword expli ...
- Qt C++中的关键字explicit——防止隐式转换(也就是Java里的装箱),必须写清楚
最近在复习QT,准备做项目了,QT Creator 默认生成的代码 explicit Dialog(QWidget *parent = 0)中,有这么一个关键字explicit,用来修饰构造函数.以前 ...
- C# 显式转换关键字 explicit
不同于隐式转换,显式转换运算符必须通过转换的方式来调用. 如果转换操作会导致异常或丢失信息,则应将其标记为 explicit. 这可阻止编译器静默调用可能产生意外后果的转换操作. 省略转换将导致编译时 ...
- c/c++拷贝构造函数和关键字explicit
c/c++拷贝构造函数和关键字explicit 关键字explicit 修饰构造方法的关键字,加上了,就告诉编译器,不可以隐式初始化对象:不加就可以隐式初始化对象: 下面的代码是可以正常编译执行的,但 ...
- 从Qt谈到C++(一):关键字explicit与隐式类型转换
转载:果冻虾仁 提出疑问 当我们新建了一个Qt的widgets应用工程时.会自动生成一个框架,包含了几个文件. 其中有个mainwindow.h的头文件.就是你要操纵的UI主界面了.我们看看其中的一段 ...
- c++关键字explicit
关键字explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生.声明为explicit的构造函数不能在隐式转换中使用. C++中, 一个参数的构造函数(或者除了第一个参数外其余参数都 ...
- 关键字explicit的作用(转)
C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况 ...
- C#的关键字Explicit 和 Implicit
一.explicit和implicit explicit 关键字用于声明必须使用强制转换来调用的用户定义的类型转换运算符:implicit 关键字用于声明隐式的用户自定义的类型转换运算符. 总结来说: ...
随机推荐
- iptables 基础知识
[root@tp ~]#iptables -L -n 查看防火墙规则 [root@tp ~]# iptables -D INPUT 1 根据命令iptables -L -n --line-numbe ...
- MvvmLight 绑定
添加MvvmLight引用,通过Nuget: 加载nuget以后会有ViewModelLocator.cs: 新建自己的ViewModel,继承ViewModelBase: View 通过资源引用Vi ...
- SQL 数据库 函数
1.数学函数:操作一个数据,返回一个结果 --取上限ceiling select code,name,ceiling(price) from car ; --取下限 floor select floo ...
- C++Builder 笔记
1.界面窗口如何不显示标题栏? 在Form属性栏里面把BorderStyle的值设为None 2.wchar_t wchar_t是C/C++的字符类型,是一种扩展的存储方式,wchar_t类型主要用在 ...
- 移动widget开发
发现Oracle----php连接有很多bug无法解决,只好转向php--连接mysql数据库,并装载了mysql两个文件,跟客户端NAVICAT_FOR_MYSQL,然后直接建表,用于测试,能够连通 ...
- paper 28 :一些常见常用数据库的下载网站集锦
做图像处理+模式识别的童鞋怎么可以没有数据库呢? 但是,如果自己做一个数据库,费时费力费钱先不说,关键是建立的数据库的公信力一般不会高,做出的算法也别人也不好比较,所以呢,下载比较权威的公共数据库还是 ...
- paper 20 :color moments
图像的颜色特征是很重要的,其中颜色矩也是很重要的一部分.(还有一个关于图像颜色特征的review,对于image color写的比较全面).还有,我要强调一下,本blog上的链接都是Google学术上 ...
- PTPX中的time_based analysis
根据VCD文件的type,PTPX支持instantaneous peak power analysis和cycle_accurate peak power analysis. Time-Based ...
- 在centos中编译putty时提示找不到gtk库的解决办法
明明已经安过gtk了, 后来在csdn上发现了前人的解决办法 yum install libgnomeui-devel 现在编译出来的putty就可以有图形界面了
- 天天模拟器 和 Genymotion 设置代理
之前以为是10.0.3.1或者本机IP,尝试几次都不行,百度之,得到答案,原来genymotion里面网关的IP是10.0.3.2 所以,代理IP要设置为:10.0.3.2