博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ 关键字 explicit, export, mutable
阅读量:6406 次
发布时间:2019-06-23

本文共 1821 字,大约阅读时间需要 6 分钟。

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型成员变量

}

 

转载地址:http://uuqea.baihongyu.com/

你可能感兴趣的文章
温州动车事故中受伤的“我”,还好吗?
查看>>
lvm实现快速备份文件及数据库,lvm快照原理
查看>>
通常,人们会高估自己的学习能力
查看>>
设计模式之Factory Method(工厂方法)
查看>>
10K入职linux运维岗位小伙伴感谢信及面试经历分享
查看>>
Gartner:智能SOC/情报驱动的SOC的五大特征
查看>>
zookeeper入门之Curator的使用之几种监听器的使用
查看>>
[转]Reporting Service部署之访问权限
查看>>
innerxml and outerxml
查看>>
validform校验框架不显示错误提示
查看>>
flink 获取上传的Jar源码
查看>>
Spring Data JPA Batch Insertion
查看>>
mongodb索引
查看>>
UEditor自动调节宽度
查看>>
JAVA做验证码图片(转自CSDN)
查看>>
Delphi TServerSocket,TClientSocket实现传送文件代码
查看>>
JS无聊之作
查看>>
Mac上搭建ELK
查看>>
443 Chapter7.Planning for High Availability in the Enterprise
查看>>
HttpHandler初探 - 页面上输出图像
查看>>