C++ 类的隐式转换

所谓类的隐式转换,就是将实参类型转成形参类型--如果不一致的话。

这个转换与基本类型转换不太一样,具体则是在形参类型的构造函数中使用实参类型的数据,从而构造出一个临时对象。

下面的代码,类Person 的成员函数 isSamePerson(const Person &person) const ,理论上需要一个 Person 引用,但实际上被传递了一个 string对象

编译器会自动调用 Person tmp(str)构造函数 来构造一个临时对象,而不是真的将 string类型 转成 Person 类型!

代码:

#include <iostream>
#include <string>

using namespace std;

class Person{
    private:
        string name;
        int id;

    public:
        Person(const string &nm=string("xxx")):name(nm),id(0){} //就不用默认无参构造了 ;隐式转换

    public:
        bool isSamePerson (const Person &person) const{ //const成员函数 ,只能调用const成员(变量、函数)!
            cout<<"比较对象:"<<person.getId()<<"--"<<person.getName()<<endl;//
            return id == person.getId(); //
        }

        const int &getId() const{ //任意一个const去掉后,都会导致问题。。。
            return id;
        }
        const string &getName() const{ //因为const修饰的是this指向的对象,所以也必须返回const引用
            return name;
        }
};

int main(){
    string a="aaa";
    Person p1(a);
    cout<<p1.getId()<<"--"<<p1.getName()<<endl;

    string b="bbb";
    cout<<p1.isSamePerson(b)<<endl; //隐式转换!!! 

    return 0;
}

尽管有时候这样的转换是我们需要的,但也有不需要的时候,这个时候,给类中的构造函数声明加上explicit,则会防止在需要隐式转换的上下文中使用该构造函数。

#include <iostream>
#include <string>

using namespace std;

class Person{
    private:
        string name;
        int id;

    public:
        explicit Person(const string &nm=string("xxx")):name(nm),id(0){} //就不用默认无参构造了 ;显式 explicit

    public:
        bool isSamePerson (const Person &person) const{ //const成员函数
            cout<<"比较对象:"<<person.getId()<<"--"<<person.getName()<<endl;//
            return id == person.getId(); //
        }

        const int &getId() const{ //任意一个const去掉后,都会导致问题。。。
            return id;
        }
        const string &getName() const{ //因为const修饰的是this指向的对象,所以也必须返回const引用
            return name;
        }
};

int main(){
    string a="aaa";
    Person p1(a);
    cout<<p1.getId()<<"--"<<p1.getName()<<endl;

    string b="bbb";
    cout<<p1.isSamePerson(Person(b))<<endl;//显式转换!!! 

    return 0;
}

结论:除非有明显的理由想要使用隐式转换,否则,单形参的构造函数应该设置为explicit

其他:前向声明只能用于使用指针或引用的情况。

时间: 2025-01-05 11:11:39

C++ 类的隐式转换的相关文章

Scala隐式转换

概述 简单说,隐式转换就是:当Scala编译器进行类型匹配时,如果找不到合适的候选,那么隐式转化提供了另外一种途径来告诉编译器如何将当前的类型转换成预期类型.本文原文出处: http://blog.csdn.net/bluishglc/article/details/50866314 严禁任何形式的转载,否则将委托CSDN官方维护权益! 隐式转换有四种常见的使用场景: 将某一类型转换成预期类型 类型增强与扩展 模拟新的语法 类型类 语法 隐式转换有新旧两种定义方法,旧的定义方法指是的"impli

effective c++条款13-17 “以对象管理资源”之C++隐式转换和转换构造函数

其实我们已经在C/C++中见到过多次标准类型数据间的转换方式了,这种形式用于在程序中将一种指定的数据转换成另一指定的类型,也即是强制转换,比如:int a = int(1.23),其作用是将1.23转换为整形1.然而对于用户自定义的类类型,编译系统并不知道如何进行转换,所以需要定义专门的函数来告诉编译系统改如何转换,这就是转换构造函数和类型转换函数! 注意:转换构造函数.隐式转换和函数对象不要搞混淆!!!函数对象是重载运算符(),和隐式转换函数易混淆. 一.转换构造函数 转换构造函数(conve

编写高质量代码——提防隐式转换带来的麻烦

在C/C++ 语言,允许在不同类型的数据之间进行某一操作或混合操作,如果类型不同,则要将数据转换成相同的数据类型(隐式转换和显示转换). ========================= 隐式转换主要发生的情形: ▉基本类型之间的隐式转换 C/C++ 中规定的两个通用转换原则: 1)为防止精度损失,类型总是被提升为较宽的类型. 2)所有含有小于整数类型的算术表达式在计算之前其类型都被转换成整形. 对于C++最直接的害处是:可能导致 重载函数 产生二义性. 例如: void Print(int

Scala中的Implicit(隐式转换,隐式参数,隐式类)

文章来自:http://www.cnblogs.com/hark0623/p/4196452.html  转发请注明 代码如下: /** * 隐式转换 隐式参数 隐式类 */ //隐式转换 class Implicit(a: A) { def Test: Unit = { println("Implicit") } } class A { } object Implicit { //隐式转换 implicit def a2Implicit(a: A) = new Implicit(a)

scala入门-10 隐式转换、隐式参数、隐式类

到目前为止,隐式转换是scala的重点和难点了,加油~ 我们先创建一个类名称叫Implicit.scala 再看一个隐式参数的例子: 上面的例子中使用了隐式参数,我们也可以明显的指明参数: 下面看一下隐式类: 相当于: 到目前为止,本人已经把所有scala在spark中开发中所涉及的基础知识练习了一遍了,稍后我会把scala其他方面知识在总结一下 谢谢大家抽出时间阅读

Scala隐式转换类遇到的问题

今天练习Scala的隐式转换类遇到的一个问题,测试代码如下: object ImplcitTest { def main(args: Array[String]) { import Context._ val person1 = User("zhangsan") println(person1.getStr()) val filePath = Thread.currentThread.getContextClassLoader.getResource("test.txt&qu

scala中隐式转换之隐式转换调用类中本不存在的方法

/** * Created by root * Description : 隐式转换调用类中本不存在的方法 */ class Person(name : String){ def getPersonName = println("name = " + name) } object Type2Type{ implicit def type2(a : ImplicitTest2) = new Person("xiaoming") } class ImplicitTest

21.C++- ++操作符重载、隐式转换之explicit关键字、类的类型转换函数

++操作符重载 ++操作符分为前置++和后置++,比如: ++a;  a++; ++操作符可以进行全局函数或成员函数重载 重载前置++操作符不需要参数 重载后置++操作符需要一个int类型的占位参数 前置++操作符的返回值为*this 后置++操作符的返回值为临时对象 例如: 转换规则如下所示: 比如: 隐式转换的隐患 隐式转换有时会因为类型不同,得到的结果大有不同,也是常见bug之一. 参考以下示例: 运行打印: 答案并非是-1000. 同样,我们使用构造函数时,也经常使用隐式转换 参考以下示

Atitit.变量的定义&#160;获取&#160;储存&#160;物理结构&#160;基本类型简化&#160;隐式转换&#160;类型推导&#160;与底层原理&#160;attilaxDSL

Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL 1.1. $ 美元字符, php 黑头1 1.2. 默认变量的范围和声明:1 1.3. 变量的存储,储存在变量池里Map(varName,varVal)1 1.3.1. 复合变量1 1.4. 变量类型简化: 字符串 数字,  bool1 1.5. 变量自动隐式转换2 1.6. 类型推导2 2. 参考 复合变量2 1.1. $ 美元字符, php 黑头 1.2. 默认变量的范围和声明