zoukankan      html  css  js  c++  java
  • non-explicite-one-argumen-constructor

    class Fraction
    {
    public:
        Fraction(int num,int den=1):m_numerator(num),m_denominator(den)
        {
            cout << "构造函数被默默调用了哦!!!" << endl;
        }
        ~Fraction(){ cout << "析构函数被默默-调用了哦!!!" << endl; }
        Fraction operator +(const Fraction& f) {
            return Fraction (......);
        }
    private:
        double m_numerator;
        double m_denominator;
    };

     

    注解:

    1. 蓝色这种函数相当特别,特别把这一种构造函数叫做non-explcit-one-argument ctor. 
    2. argument代表实参,但后一个参数有初值,所以此时要创建一个Fraction的对象,只要提供一个实参就行了。因为第二个实参有默认值。这样的设计是合理的,因为在数学上,3等于1分之3,分母默认1.
    3. 这个蓝色背景的函数属于two parameter, one argument.后者的意思是只要一个实参就够了。给两个实参也可以的。
    4. explicite是个关键字,可以出现在构造函数的前面,现在没有出现,所以就叫做non-explicit-one-argument ctor.
    5. Fraction d2=f+4; 这一句会让编译器寻找‘+’这个动作,它找到了,就是函数operator+() . +要作用在左边的操作数上,左边的f调用+,但是它发现+的右边的操作数也是一个Fraction(注意,类的成员函数有个隐含的this指针),而实际调用的时候却是f+4,右边的操作数不是Fraction类型的对象。此时编译器会看看能不能把4转换为Fraction类型的对象,如果有4能转换为Fraction,那就是分数+分数,就符合那个成员函数的设计了。因此,现在编译器考虑的是4能不能转换成Fraction,4就是4/1,它发现蓝色区域的代码可以把4转变为分数。所以Fraction d2=f+4; 这一句会首先调用non-explicit ctor 将4转为Fraction(4,1),然后调用operator +()这个函数。
    6. Fraction d2=f+4; 这句相当于Fraction d2=f(3,5)+f(4,1). (来自网友弹幕)
    7. 别(内置)的类转变为Fraction,而上一讲是Fraction转变为别(内置)的类。方向正好相反。
    #pragma once
    #include<iostream>
    using namespace std;
    class Fraction
    {
    public:
        Fraction(int num,int den=1):m_numerator(num),m_denominator(den)
        {
            cout << "构造函数被默默调用了哦!!!" << endl;
        }
        operator double() const {
            return (double)(m_numerator/ m_denominator);
        }
        ~Fraction(){ cout << "析构函数被默默-调用了哦!!!" << endl; }
        Fraction operator +(const Fraction& f) {
            return Fraction (......);
        }
    private:
        double m_numerator;
        double m_denominator;
    };
    #include <iostream>
    using namespace std;
    #include"conversion_function.h"
    void main()
    {
        Fraction f(3,5);
        cout << "The fraction f is: "<<f << endl;
        Fraction d2=f+4;
        cout << "The fraction d2 is: " << d << endl;
        system("pause");
    }

    注解:

    1. 若有红色和橙色两个函数,编译器遇到Fraction d2=f+4; 时,就不知道该怎么办了。因为不知道是应该调用橙色部分的函数把f转换为double(3/5转变为0.6,0.6+4=4.6,4.6能不能再转为Fraction呢?),还是应该调用粉红色部分把4(double)转换为Fraction.
    2. 如果一句代码有两条路可以走,则会出现歧义,此时会出现Error错误。
    3. d2的数据类型改为double 才会ambiguous 把?(网友弹幕)
    4. double可以默认转换为int(网友弹幕)
    #pragma once
    #include<iostream>
    using namespace std;
    class Fraction
    {
    public:
        explicit Fraction(int num,int den=1):m_numerator(num),m_denominator(den)
        {
            cout << "构造函数被默默调用了哦!!!" << endl;
        }
        operator double() const {
            return (double)(m_numerator/ m_denominator);
        };
        ~Fraction(){ cout << "析构函数被默默-调用了哦!!!" << endl; }
        Fraction operator +(const Fraction& f) {
            return Fraction (3,9);
        }
    private:
        double m_numerator;
        double m_denominator;
    };
    #include <iostream>
    using namespace std;
    #include"conversion_function.h"
    void main()
    {
        Fraction f(3,5);
        cout << "The fraction f is: "<<f << endl;
        Fraction d2=f+4;
        cout << "The fraction d2 is: " << d << endl;
        system("pause");
    }

     注解:

    1. explicit意思是明确的,加上explicit意思就是告诉编译器,我这个构造函数是明确的构造函数,只用于构造对象,不用于类型转换,不要自动把double转换为Fraction哦.
    2. Fraction d2=f+4; 编译器再遇到这一行的时候,就不会把4转变为4/1了,因为构造函数的前面加了关键字explicit.
    3. Fraction d2=f+4; 编译器遇到这一句就会去调用+的重载函数了,但重载函数的右操作数类型是Fraction,而4不会被转变为Fraction,所以会出错。报错信息为:[Error] conversion from "double" to 'Fraction' requested.
    4. 此时为何不把Fraction转变为double?(网友弹幕)
    5. 这里的问题应该出现在4.6(double)转换为Fraction的时候转换不过去(网友弹幕)
  • 相关阅读:
    数组和函数
    循环练习题
    JavaScript 循环
    函数
    JavaScript简介2
    JS练习题1
    JavaScript简介
    css样式综合
    格式与布局
    列表和方块
  • 原文地址:https://www.cnblogs.com/yibeimingyue/p/13513878.html
Copyright © 2011-2022 走看看