随笔 - 1760  文章 - 0  评论 - 109  阅读 - 431万

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的时候转换不过去(网友弹幕)

 

posted on   一杯明月  阅读(304)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示