0
点赞
收藏
分享

微信扫一扫

Mac端口扫描工具

IT程序员 2024-09-24 阅读 37

操作符重载

操作符重载(operator overoading)是一种形式的 C++多态。

第8章介绍了C++是如何使用户能够定义多个名称相同但特征标(参数列表)不同的函数的。这被称为函数重载(function overloading)或函数多态(functional polymorphism),旨在让您能够用同名的函数来完成相同的基本操作,即使这种操作被用于不同的数据类型

实际上,很多 C++(也包括C语言)操作符已经被重载。例如,将*操作符用于地址,将得到存储在这个地址中的值;但将它用于两个数字时,得到的将是它们的乘积。C++根据操作数的数目和类型来决定采用哪种操作。

数组加法

op是将要重载的操作符。例如,operator +()重载+操作符,operator*()重载*操作符。op 必须是有效的 C++操作符,不能虚构一个新的符号。例如,不能有 operator@()这样的函数,因为 C++中没有@操作符。

操作符重载范例

mytime0.h

// mytime0.h-- Time class before operator overloading
#ifndef MYTIMEO H
#define MYTIMEO H
class Time
{
private:
    int hours;
    int minutes;

public:
    Time();
    Time(int h, int m = 0);
    void AddMin(int m);
    void AddHr(int h);
    void Reset(int h = 0, int m = 0);
    Time Sum(const Time &t) const;
    void Show() const;
};
#endif

Sum()函数的代码。注意参数是引用,但返回类型却不是引用。将参数声明为引用的目的是为了提高效率。如果按值传递Time 对象,代码的功能将相同,但传递引用,速度将更快,使用的内存将更少。

mytime0.cpp

// mytime0.cpp--implement Time methods
#include <iostream>
#include "mytime0.h"
Time::Time()
{
    hours = minutes = 0;
}

Time::Time(int h, int m)
{
    hours = h;
    minutes = m;
}

void Time::AddMin(int m)
{
    minutes += m;
    hours += minutes / 60;
    minutes %= 60;
}

void Time::AddHr(int h)
{
    hours += h;
}

void Time::Reset(int h, int m)
{
    hours = h;
    minutes = m;
}
Time Time::Sum(const Time &t) const
{
    Time sum;
    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + sum.minutes / 60;
    sum.minutes %= 60;
    return sum;
}
void Time::Show() const
{
    std::cout << hours << " hours. " << minutes << "minutes";
}

usetime0.cpp

#include <iostream>
#include "mytime0.h"
int main()
{
    using std::cout;
    using std::endl;
    Time planning;
    Time coding(2, 40);
    Time fixing(5, 55);
    Time total;
    cout << "planning time =";
    planning.Show();
    cout << endl;
    cout << "coding time =";
    coding.Show();
    cout << endl;
    cout << "fixing time =";
    fixing.Show();
    cout << endl;
    total = coding.Sum(fixing);
    cout << "coding.Sum(fixing)=";
    total.Show();

    return 0;
}

添加加法操作符

将 Time 类转换为重载的加法操作符很容易,只要将 Sum()的名称改为 operator+()即可。这样做是对的,只要把操作符(这里为+)放到operator的后面,并将结果用作方法名即可。在这里,可以在标识符中使用字母、数字或下划线之外的其他字符。

mytime1.h

// mytime0.h-- Time class before operator overloading
#ifndef MYTIMEO H
#define MYTIMEO H
class Time
{
private:
    int hours;
    int minutes;

public:
    Time();
    Time(int h, int m = 0);
    void AddMin(int m);
    void AddHr(int h);
    void Reset(int h = 0, int m = 0);
    // Time Sum(const Time &t) const;
    Time operator+(const Time &t) const;
    void Show() const;
};
#endif

mytime1.cpp

// mytime0.cpp--implement Time methods
#include <iostream>
#include "mytime0.h"
Time::Time()
{
    hours = minutes = 0;
}

Time::Time(int h, int m)
{
    hours = h;
    minutes = m;
}

void Time::AddMin(int m)
{
    minutes += m;
    hours += minutes / 60;
    minutes %= 60;
}

void Time::AddHr(int h)
{
    hours += h;
}

void Time::Reset(int h, int m)
{
    hours = h;
    minutes = m;
}
Time Time::operator+(const Time &t) const
{
    Time sum;
    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + sum.minutes / 60;
    sum.minutes %= 60;
    return sum;
}
void Time::Show() const
{
    std::cout << hours << " hours. " << minutes << "minutes";
}

usetime1.cpp

#include <iostream>
#include "mytime0.h"
int main()
{
    using std::cout;
    using std::endl;
    Time planning;
    Time coding(2, 40);
    Time fixing(5, 55);
    Time total;
    cout << "planning time =";
    planning.Show();
    cout << endl;
    cout << "coding time =";
    coding.Show();
    cout << endl;
    cout << "fixing time =";
    fixing.Show();
    cout << endl;
    total = coding + fixing;
    cout << "coding + fixing=";
    total.Show();
    cout << endl;

    Time morefixing(3, 28);
    cout << "more fixing time = ";
    morefixing.Show();
    cout << endl;
    total = morefixing.operator+(total); // function notation
    cout << "morefixing.operator+(total)=";
    total.Show();
    cout << endl;
    return 0;
}

重载限制

重载的操作符(有些例外情况)不必是成员函数,但必须至少有一个操作数是用户定义的类型

其他重载操作符

时间的减和乘

mytime2.h

// mytime0.h-- Time class before operator overloading
#ifndef MYTIMEO H
#define MYTIMEO H
class Time
{
private:
    int hours;
    int minutes;

public:
    Time();
    Time(int h, int m = 0);
    void AddMin(int m);
    void AddHr(int h);
    void Reset(int h = 0, int m = 0);
    // Time Sum(const Time &t) const;
    Time operator+(const Time &t) const;
    Time operator-(const Time &t) const;
    Time operator*(double n) const;
    void Show() const;
};
#endif

mytime2.cpp

// mytime0.cpp--implement Time methods
#include <iostream>
#include "mytime0.h"
Time::Time()
{
    hours = minutes = 0;
}

Time::Time(int h, int m)
{
    hours = h;
    minutes = m;
}

void Time::AddMin(int m)
{
    minutes += m;
    hours += minutes / 60;
    minutes %= 60;
}

void Time::AddHr(int h)
{
    hours += h;
}

void Time::Reset(int h, int m)
{
    hours = h;
    minutes = m;
}
Time Time::operator+(const Time &t) const
{
    Time sum;
    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + sum.minutes / 60;
    sum.minutes %= 60;
    return sum;
}
Time Time::operator-(const Time &t) const
{
    Time diff;
    int tot1, tot2;
    tot1 = t.minutes + 60 * t.hours;
    tot2 = minutes + 60 * hours;
    diff.minutes = (tot2 - tot1) % 60;
    diff.hours = (tot2 - tot1) / 60;
    return diff;
}
Time Time::operator*(double mult) const
{
    Time result;
    long totalminutes = (minutes + 60 * hours) * mult;
    result.minutes = totalminutes % 60;
    result.hours = totalminutes / 60;
    return result;
}
void Time::Show() const
{
    std::cout << hours << " hours. " << minutes << "minutes";
}

usetime2.cpp

#include <iostream>
#include "mytime0.h"
int main()
{
    using std::cout;
    using std::endl;
    Time weeding(4, 35);
    Time waxing(2, 47);
    Time total;
    Time diff;
    Time adjusted;

    cout << "weeding time =";
    weeding.Show();
    cout << endl;

    cout << "waxing time =";
    waxing.Show();
    cout << endl;

    cout << "total time =";
    total = weeding + waxing;
    cout << "coding + fixing=";
    total.Show();
    cout << endl;

    diff = weeding - waxing;
    cout << "coding - fixing=";
    diff.Show();
    cout << endl;

    adjusted = total * 1.5;
    cout << "Adjusted work time = ";
    total.Show();
    cout << endl;
    return 0;
}

友元简介

C++控制对类对象私有部分的访问。通常,公有类方法提供惟一的访问途径,但是有时候这种限制太严格,以致上不适合特定的编程问题。在这种情况下,C++提供了另外一种形式的访问权限:
友元。

友元有三种:

介绍如何成为友元之前,先介绍为何需要友元。在为类重载一元操作符时(带两个参数的操作符)常常需要友元。将Time对象乘以实数就属于这种情况

从概念上说,2.75*B应与 B*2.75 相同,但第一个表达式不对应于成员函数,因为 2.75 不是 Time 类型的对象。记住,左侧的操作数应是调用对象,但2.75不是对象。因此,编译器不能使用成员函数调用来替换该表达式。

决这个难题的一种方式是,告知每个人(包括程序员自己),只能按B*2.75 这种格式编写,不能写成 2.75*B。这是一种对服务器友好-客户警惕的(server-ffiendly,client-beware)解决方案,与OOP无关。

(无法直接访问B中的内容)

创建友元

创建友元函数的第是将其原型放在类声明中,并在原型声明前加上关键字friend


第二步是编写函数定义。因为它不是成员函数,所以不要使用Time:限定符。另外,不要在定义中使用关键字 friend,定义应该如下:

常用的友元:重载<<操作符

 之所以可以这样做,是因为<<是可被重载的 C++操作符之一

前面讲过,cout 是一个 ostream 对象,它是智能的,能够识别所有的 C++基本类型。这是因为对于每种基本类型,ostream类声明中都包含了相应的重载的 operator<<()定义

因此,要使 cout 能够识别 Time 对象,一种方法是将一个新的函数操作符定义添加到 ostream 类声明中。但修改iostream 文件是个危险的主意,这样做会在标准接口上浪费时间。更好的办法是,通过Time类声明来让 Time 类知道如何使用 cout

<<第一种重载版本

司用 cout<<trip 应使用cout对象本身,而不是它的拷贝,因此该函数按引用(而不是按值)来传递该对象。这样,表达式 cout<<trip 将导致 os 成为 cout 的一个别名;而表达式 cenr <<trip 将导致 os 成为 cen
的一个别名。Time对象可以按值或按引用来传递,因为这两种形式都使函数能够使用对象的值。按引用传递使用的内存和时间都比按值传递少。

<<第二种重载版本

问题:

例如

修改方法

调用os类的引用所以

特别的

头文件

// mytime0.h-- Time class before operator overloading
#ifndef MYTIME0_H_
#define MYTIME0_H_
class Time
{
private:
    int hours;
    int minutes;

public:
    Time();
    Time(int h, int m = 0);
    void AddMin(int m);
    void AddHr(int h);
    void Reset(int h = 0, int m = 0);
    // Time Sum(const Time &t) const;
    Time operator+(const Time &t) const;
    Time operator-(const Time &t) const;
    Time operator*(double n) const;
    friend Time operator*(double m, const Time &t)
    {
        return t * m;
    } // inline definition
    friend std::ostream &operator<<(std::ostream &os, const Time &t);
};
#endif

其中包括 operator*()和 operator<<()这两个友元函数。它将第-个友元函数作为内联函数,因为其代码很短(当定义同时也是原型时,就像这个例子中那样,要使用 fiend前缀)。

源代码

// mytime0.cpp--implement Time methods
#include <iostream>
#include "mytime0.h"
Time::Time()
{
    hours = minutes = 0;
}

Time::Time(int h, int m)
{
    hours = h;
    minutes = m;
}

void Time::AddMin(int m)
{
    minutes += m;
    hours += minutes / 60;
    minutes %= 60;
}

void Time::AddHr(int h)
{
    hours += h;
}

void Time::Reset(int h, int m)
{
    hours = h;
    minutes = m;
}
Time Time::operator+(const Time &t) const
{
    Time sum;
    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + sum.minutes / 60;
    sum.minutes %= 60;
    return sum;
}
Time Time::operator-(const Time &t) const
{
    Time diff;
    int tot1, tot2;
    tot1 = t.minutes + 60 * t.hours;
    tot2 = minutes + 60 * hours;
    diff.minutes = (tot2 - tot1) % 60;
    diff.hours = (tot2 - tot1) / 60;
    return diff;
}
Time Time::operator*(double mult) const
{
    Time result;
    long totalminutes = (minutes + 60 * hours) * mult;
    result.minutes = totalminutes % 60;
    result.hours = totalminutes / 60;
    return result;
}
std::ostream &operator<<(std::ostream &os, const Time &t)
{
    os << t.hours << " hours, " << t.minutes << " minutes";
    return os;
}

源代码

#include <iostream>
#include "mytime0.h"
int main()
{
    using std::cout;
    using std::endl;
    Time aida(3, 35);
    Time tosca(2, 48);
    Time temp;

    cout << "Aida and Tosca:\n";
    cout << aida << ";" << tosca << endl;
    temp = aida + tosca; // operator+()
    cout << "Aida + Tosca:" << temp << endl;
    temp = aida * 1.17; // member operator*()
    cout << "Aida*l.17:" << temp << endl;
    cout << "10*Tosca:" << 10 * tosca << endl;
    return 0;
}

重载操作符:作为成员函数还是非成员函数

两种加法操作符

对于两种加法

定义操作符时候只能使用其中一种格式,不然会产生歧义。

重载:矢量类

头文件

// vect.h--Vector class with<<,mode state
#ifndef VECTOR_H_
#define VECTOR_H_
#include <iostream>
namespace VECTOR
{
    class Vector
    {

    private:
        double x;
        double y;
        double mag;
        char mode;
        double ang;
        void set_mag();
        void set_ang();
        void set_x();
        void set_y();

    public:
        Vector();
        Vector(double nl, double n2, char form = 'r');
        void set(double nl, double n2, char form = 'r');
        ~Vector();
        double xval() const { return x; }     // report x value
        double yval() const { return y; }     // report y value
        double magval() const { return mag; } // report magnitude
        double angval() const { return ang; } // report angle
        void polar_mode();
        void rect_mode(); // operator overloading
        Vector operator+(const Vector &b) const;
        Vector operator-(const Vector &b) const;
        Vector operator-() const;
        Vector operator*(double n) const;
        friend Vector operator*(double n, const Vector &a);
        friend std::ostream &operator<<(std::ostream &os, const Vector &v);
    };

} // end namespace VECTOR
#endif

源代码

// vector.cpp --methods for Vector class
#include <cmath>
#include "vector.h"
#include <iostream>
using std::atan2;
using std::cos;
using std::cout;
using std::sin;
namespace VECTOR
{
    const double Rad_to_deg = 57.2957795130823;
    // private methods
    // calculates magnitude from x and y
    void Vector::set_mag()
    {
        mag = sqrt(x * x + y * y);
    }
    void Vector::set_ang()
    {
        if (x == 0.0 && y == 0.0)
            ang = 0.0;
        else
            ang = atan2(y, x);
    }

    // set xfrom polar coordinate
    void Vector::set_x()
    {
        x = mag * cos(ang);
    }

    // set y from polar coordinate
    void Vector::set_y()
    {
        y = mag * sin(ang);
    }

    // public methods
    Vector::Vector() // default constructor
    {
        x = y = mag = ang = 0.0;
        mode = 'r';
    }
    Vector::Vector(double n1, double n2, char form)
    {
        mode = form;
        if (form == 'r')
        {
            x = n1;
            y = n2;
            set_mag();
            set_ang();
        }
        else if (form == 'p')
        {
            mag = n1;
            ang = n2 / Rad_to_deg;
            set_x();
            set_y();
        }
        else
        {
            cout << "Incorrect 3rd argument to Vector()-- ";
            cout << "vector set to 0\n";
            x = y = mag = ang = 0.0;
            mode = 'r';
        }
    }

    // set vector from rectangular coordinates if form is r(the
    // default)or else from polar coordinates if form is p
    void Vector::set(double n1, double n2, char form)
    {
        mode = form;
        if (form == 'r')
        {
            x = n1;
            y = n2;
            set_mag();
            set_ang();
        }
        else if (form == 'p')
        {
            mag = n1;
            ang = n2 / Rad_to_deg;
            set_x();
            set_y();
        }
        else
        {
            cout << "Incorrect 3rd argument to Vector()-- ";
            cout << "vector set to 0\n";
            x = y = mag = ang = 0.0;
            mode = 'r';
        }
    }

    Vector::~Vector()
    {
    } // destructor
    void Vector::polar_mode() // set to polar  mode
    {
        mode = 'p';
    }
    void Vector::rect_mode() // set to rectangular mode
    {
        mode = 'r';
    }
    // operator overloading
    //  add two Vectors
    Vector Vector::operator+(const Vector &b) const
    {
        return Vector(x + b.x, y + b.y);
    }
    // subtract Vector b from a
    Vector Vector::operator-(const Vector &b) const
    {
        return Vector(x - b.x, y - b.y);
    }
    // reverse sign of Vector
    Vector Vector::operator-() const
    {
        return Vector(-x, -y);
    }
    // multiple vector by n
    Vector Vector::operator*(double n) const
    {
        return Vector(n * x, n * y);
    }
    // friend methods
    // multiply n byVector a
    Vector operator*(double n, const Vector &a)
    {
        return a * n;
    }

    // display rectangular coordinates if mode is r
    // else display polar coordinates if mode is p
    std::ostream &operator<<(std::ostream &os, const Vector &v)
    {
        if (v.mode == 'r')
        {
            os << "(x,y)=(" << v.x << "," << v.y << ")";
        }
        else if (v.mode == 'p')
        {
            os << "(m,a)=(" << v.mag << ","
               << v.ang * Rad_to_deg << ")";
        }
        else
            os << "Vector object mode is invalid";
        return os;
    }
} // end namespace VECTOR

使用状态成员

状态成员

为Vector类重载操作符

加法

可以使用的加法(无法使用极坐标)

改进

采用的加法(简单)

乘法

友元内联函数来解决乘法交换顺序的问题

对已重载的操作符进行重载

减法(二元操作符)

取反(一元操作符)

模拟随机游走

// randwalk.cpp-…using the Vector class
// compile with the vect.cpp file
#include <iostream>
// rand(),srand()prototypes// time()prototype
#include <cstdlib>
#include <ctime>
#include "vector.h"
int main()
{
    using namespace std;
    using VECTOR::Vector;
    srand(time(0)); // seed random - number generator
    double direction;
    Vector step;
    Vector result(0.0, 0.0);
    unsigned long steps = 0;
    double target;
    double dstep;
    cout << "Enter target distance(q to quit):";
    while (cin >> target)
    {
        cout << "Enter step length:";
        if (!(cin >> dstep))
            break;
        while (result.magval() < target)
        {
            direction = rand() % 360;
            step.set(dstep, direction, 'p');
            result = result + step;
            steps++;
        }
        cout << "After " << steps << " steps, the subject"
                                     " has the following location : \n ";
        cout << result << endl;
        result.polar_mode();
        cout << " or\n " << result << endl;
        cout << " Average outward distance per step = "
             << result.magval() / steps << endl;
        steps = 0;
        result.set(0.0, 0.0);
        cout << "Enter target distance(qto quit):";
    }

    cout << "Bye!\n";
    return 0;
}

类的自动转换和强制类型转换

内置类型转换

将一个标准类型变量的值赋给另一种标准类型的变量时,如果这两种类型兼容,则C++自动将这个值转换为接收变量的类型。

例如

不兼容的类型不能自动转换

但是可以进行强制类型转换

类的转换

可以将类定义成与基本类型或另一个类相关,使得从一种类型转换为另一种类型是有意义的。

stonewt.h

// stonewt.h --definition forStonewtCass
#ifndef STONEWT_H_
#define STONEWT_H_
class Stonewt
{
private:
    enum
    {
        Lbs_per_stn = 14
    }; // pounds per stone
    int stone;       // whole stones
    double pds_left; // fractional pounds
    double pounds;   // entire weight in pounds

public:
    Stonewt(double lbs);          // constructor for double pounds
    Stonewt(int stn, double lbs); // constructor for stone,1bs
    Stonewt();                    // default constructor
    ~Stonewt();

    void show_lbs() const;
    // show weight in pounds format
    void show_stn() const;
    // show weight in stone format}
};

#endif

源文件

#include <iostream>
using std::cout;
#include "stonewt.h"
// construct Stonewt object from double value
Stonewt::Stonewt(double lbs)
{
    stone = int(lbs) / Lbs_per_stn; // integer division
    pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);
    pounds = lbs;
}

// construct Stonewt obiect from stone,double values
Stonewt::Stonewt(int stn, double lbs)
{
    stone = stn;
    pds_left = lbs;
    pounds = stn * Lbs_per_stn + lbs;
}

Stonewt::Stonewt() // default constructor,wt=0
{
    stone = pounds = pds_left = 0;
}

Stonewt::~Stonewt()
// destructor
{
}
// show weight in stones
void Stonewt::show_stn() const
{
    cout
        << stone << "stone," << pds_left << "pounds\n";
}
// show weight in pounds
void Stonewt::show_lbs() const
{
    cout << pounds << "pounds\n";
}

对于函数

 接受两个参数的不可以不能作为转换函数

避免意外的类型转换

最新的C++实现新增了一个关键字(explicit),用来关闭这种自动特性。也就是说,可以这样声明构造函数:

但是仍可以进行显示强制类型转换

隐式转换

不发生歧义下,会进行二步转换

下面两条语句都首先将int转换为double,然后使用 Stonewt(double)构造函数。

#include <iostream>
using std::cout;
#include "stonewt.h"
void display(const Stonewt &st, int n);
int main()
{
    Stonewt pavarotti = 260; // uses constructor to initialize
    Stonewt wolfe(285.7);    // same as Stonewt wolfe =285.7
    Stonewt taft(21.8);
    cout << "The tenor weighed ";
    pavarotti.show_stn();
    cout << "The detective weighed ";
    wolfe.show_stn();
    cout << "The President weighed ";
    taft.show_lbs();
    pavarotti = 265.8;
    // uses constructor for conversion
    taft = 325; // same as taft= Stonewt(325);
    cout << "After dinner,the tenor weighed ";
    pavarotti.show_stn();
    cout << "After dinner,the President weighed ";
    taft.show_lbs();
    display(taft, 2);
    cout << "The wrestler weighed even more,\n";
    display(422, 2);
    cout << "No stone left unearned\n";
    return 0;
}

void display(const Stonewt &st, int n)
{
    for (int i = 0; i < n; i++)
    {
        cout << "Wow!";
        st.show_stn();
    }
}

二步转换

转换函数

如果定义了转换函数下列就是可行的

转换函数声明

更改上述代码

// stonewt.h --definition forStonewtCass
#ifndef STONEWT_H_
#define STONEWT_H_
class Stonewt
{
private:
    enum
    {
        Lbs_per_stn = 14
    }; // pounds per stone
    int stone;       // whole stones
    double pds_left; // fractional pounds
    double pounds;   // entire weight in pounds

public:
    Stonewt(double lbs);          // constructor for double pounds
    Stonewt(int stn, double lbs); // constructor for stone,1bs
    Stonewt();                    // default constructor
    ~Stonewt();

    void show_lbs() const;
    // show weight in pounds format
    void show_stn() const;
    // show weight in stone format}
    // conversion functions
    operator int() const;
    operator double() const;
};

#endif

源文件

#include <iostream>
using std::cout;
#include "stonewt.h"
// construct Stonewt object from double value
Stonewt::Stonewt(double lbs)
{
    stone = int(lbs) / Lbs_per_stn; // integer division
    pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);
    pounds = lbs;
}

// construct Stonewt obiect from stone,double values
Stonewt::Stonewt(int stn, double lbs)
{
    stone = stn;
    pds_left = lbs;
    pounds = stn * Lbs_per_stn + lbs;
}

Stonewt::Stonewt() // default constructor,wt=0
{
    stone = pounds = pds_left = 0;
}

Stonewt::~Stonewt()
// destructor
{
}
// show weight in stones
void Stonewt::show_stn() const
{
    cout
        << stone << "stone," << pds_left << "pounds\n";
}
// show weight in pounds
void Stonewt::show_lbs() const
{
    cout << pounds << "pounds\n";
}

Stonewt::operator double() const
{
    return pounds;
}
Stonewt::operator int() const
{
    return int(pounds + 0.5);
}

源文件

#include <iostream>
#include "stonewt.h"
int main()
{
    using std::cout;
    Stonewt poppins(9, 2.8); // 9 stone,2.8 pounds
    double p_wt = poppins;   // implicit conversion
    cout << "Convert to double =>";
    cout << "Poppins:" << p_wt << " pounds.\n";
    cout << "Convert to int =>";
    cout << "Poppins:" << int(poppins) << " pounds.\n";
    return 0;
}

最好使用显式转换,而避免隐式转换。关键字 explicit 不能用于转换函数,但只需用一个功能相同的非转换函数替换该转换数即可,但仅在被显式地调用时,该函数才会执行。也就是说,可以将:

 转换函数和友元函数

重载加法的两种方式

成员函数

 友元函数

 下列合理

进行状态转换

只有友元函数允许

原因:

举报

相关推荐

0 条评论