http://www.cnblogs.com/chio/archive/2007/09/17/895263.html

c++中的explicit关键字用来修饰类的构造函数,表明该构造函数是显式(调用)的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?

如果c++类的构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数参数对应数据类型的数据转换为该类对象,如下面所示:

class MyClass
{
public:
MyClass(int num){};
}; MyClass obj = ;//10被隐式调用构造函数转换为MyClass类型对象

在上面的代码中编译器自动将整型转换为MyClass类对象,实际上等同于下面的操作:
MyClass temp(10);
MyClass obj = temp;
上面的所有的操作即是所谓的"隐式转换"。

如果要避免这种自动转换的功能,我们该怎么做呢?这就是关键字explicit的作用了,将类的构造函数声明为"显式",也就是在声明构造函数的时候前面添加上explicit即可,这样就可以防止这种自动的转换操作,如果我们修改上面的MyClass类的构造函数为显式的,那么下面的代码就不能够编译通过了,如下所示:

class MyClass
{
public:
explicit MyClass(int num){};
}; MyClass obj = ;//出错

class Rational
{
public:
Rational(int numerator = , int denominator = )
{
this->numerator = numerator;
this->denominator = denominator;
}
~Rational(){}
int get_numerator()
{
return numerator;
}
int get_denominator()
{
return denominator;
} const Rational operator*(const Rational &rhs) const; private:
int numerator;
int denominator;
}; const Rational Rational::operator*(const Rational &rhs) const
{
return Rational(numerator * rhs.numerator, denominator*rhs.denominator);
} int main()
{
Rational a(, );
//Rational b = 2 * a;//编译出错,相当于2.operator*(a),而2不是Rational类型
Rational b = a * ;//2会被隐式类型转换为Rational对象
cout << b.get_numerator() << " " << b.get_denominator() << endl; system("pause");
return ;
}

上述有理数运算不满足交换律,所以需要改进

class Rational
{
public:
Rational(int numerator = , int denominator = )
{
this->numerator = numerator;
this->denominator = denominator;
}
~Rational(){}
int get_numerator() const
{
return numerator;
}
int get_denominator() const
{
return denominator;
} private:
int numerator;
int denominator;
}; const Rational operator*(const Rational& lhs,const Rational &rhs)
{
return Rational(lhs.get_numerator() * rhs.get_numerator(), lhs.get_denominator()*rhs.get_denominator());
} int main()
{
Rational a(, );
//2会被隐式类型转换为Rational对象
Rational b = * a;
//Rational b = a * 2;
cout << b.get_numerator() << " " << b.get_denominator() << endl; system("pause");
return ;
}

总结:如果你需要为某个函数的所有参数进行类型转换,那么这个函数必须是个non-member(effective c++ 条款24)

绝不要返回指针或引用指向一个local stack对象,因为local stack对象当退出函数时就被析构了,也就是说指针或者引用指向未知的内存;不要返回引用指向一个heap-allocated对象,会导致内存泄漏;不要返回指针或引用指向一个local static对象,因为有可能同时需要多个这样的对象,此时这些对象其实都是同一个对象。所以一个必须返回新对象的函数的正确写法是:让那个函数返回一个新对象,不用担心拷贝构造函数导致的性能损失。例子可见上面的operator*的写法(effective c++ 条款21)

【c++】【转】c++中的explicit关键字的更多相关文章

  1. C++中的explicit关键字的用法

    一.explicit作用: 在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换. 二.explicit使用注意事项: ...

  2. C++中的explicit关键字

    http://www.cnblogs.com/winnersun/archive/2011/07/16/2108440.html 上面链接中的博主写的很好,我也不多说了.举得例子也很好,应该也是看了E ...

  3. C++中的explicit关键字 - 抑制隐式转换(转)

    在C++程序中很少有人去使用 explicit 关键字,不可否认,在平时的实践中确实很少能用的上.再说C++的功能强大,往往一个问题可以利用好几种C++特性去解决.但稍微留心一下就会发现现有的MFC库 ...

  4. C++中的explicit关键字(转)

    按默认规定,只用传一个参数的构造函数也定义了一个隐式转换.举个例子: #pragma once class CExample { public: CExample(void); CExample(); ...

  5. C++ explicit关键字详解

    本文系转载,原文链接:http://www.cnblogs.com/ymy124/p/3632634.html 首先, C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用 ...

  6. explicit关键字

    C++中,explicit关键字用来修饰类只有一个参数的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换. explicit使用注意事项: explicit 关 ...

  7. C++explicit关键字

    在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换. explicit使用注意事项: *     explicit  ...

  8. C++ explicit关键字详解(转载)

    转载:https://www.cnblogs.com/ymy124/p/3632634.html 首先, C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函 ...

  9. C++ explicit 关键字

    原文转自:http://www.cnblogs.com/ymy124/p/3632634.html 首先, C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造 ...

随机推荐

  1. C++ 多态、虚函数、虚析构函数

    1.若某种语言只支持类但不支持多态,则只能称为基于对象,不能说是面向对象. 2.多态:向不同对象发送同一个消息,不同的对象会产生不同的行为,发送消息可以是调用函数等操作.函数重载.运算符重载都是多态. ...

  2. Swift 性能相关

    起初的疑问源自于「在 Swift 中的, Struct:Protocol 比 抽象类 好在哪里?」.但是找来找去都是 Swift 性能相关的东西.整理了点笔记,供大家可以参考一下. 一些疑问 在正题开 ...

  3. 使用Gson解析Json数组遇到的泛型类型擦除问题解决方法

    谷歌Gson转换Json串有如下方法: public Object fromJson(String json, Type typeOfT);1可以使用它进行数组解析.如下,使用此方法解析Json串为类 ...

  4. MFC程序最小化到系统托盘及其响应函数

    预备知识: Windows API函数: WINSHELLAPI BOOL WINAPI Shell_NotifyIcon( DWORD dwMessage, PNOTIFYICONDATA pnid ...

  5. vue中的main.js打开直接报错问题解决

    安装好后也是报这样的错,是因为WebStorm默认使用的是ES5的语法,改成ES6就可以了.   解决方案:    

  6. eclipse包分层

    方法很简单,如下图所示: 1.点击项目栏窗口的右上角的倒三角 2.选择Pachage Presentation(包呈现) 3.选择Hierarchical(分层)

  7. Conv1D和Conv2D的区别

    我的答案是,在Conv2D输入通道为1的情况下,二者是没有区别或者说是可以相互转化的.首先,二者调用的最后的代码都是后端代码(以TensorFlow为例,在tensorflow_backend.py里 ...

  8. 数据库的ACID 简谈

    一.事务 定义:所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位. 准备工作:为了说明事务的ACID原理,我们使用银行账户及资金管理的案例进行分析. 二.ACI ...

  9. CentOS7安装Tomcat9并设置开机启动

    1.下载 Tomcat 9 CentOS 7 下创建目录并下载文件: cd /usr/local/ mkdir tomcat cd tomcat wget http://mirrors.hust.ed ...

  10. IDEA基本使用及配置(2)

    IDEA配置:File >> Setiings进入配置界面 1.主题配置:默认两种主题,黑色.白色,可以自己在网上下载,然后File >> Import Setiings导入, ...