细谈C++的运算符重载

什么是运算符重载?

顾名思义就是将原本的操作符以我们的方式定义出来,方便我们使用。

为什么要进行运算符重载?

简单的理由就是将减少程序员的工作量,首先先看一个简单的例子:

class A{
public:
    A(int data):data(data){};
    void show(){
        cout << "data = " << data << endl;
    }   
private:
    int data;
};
int main(int ac, char *av[])
{
    A a1(100), a2(200);

    (a1+a2).show(); //请注意这一句我们可以这样吗?编译一下看看                                                                                            
    return 0;
}      
编译结果:
[[email protected] day11]# cc.sh overload_operator.cpp 
========================   C++_program Compling  =====================       
overload_operator.cpp: In function ‘int main(int, char**)’:
overload_operator.cpp:17: error: no match for ‘operator+’ in ‘a1 + a2’
             ERROR g++ -o  overload_operator.cpp -g -lpthread

这样的结果并不是我们想要的,我们只是想相加一下两个对象里面数据并且将结果显示出来,但是操作符“+”的左右两边的变量必须是内置变量类型。所以为了方便,我们可以为我们自定义类型的对象对操作符“+”进行运算符重载,进行如下更改:

class A{
public:
    A(int data):data(data){};
    void show(){
        cout << "data = " << data << endl;
    }  
    // 运算符重载函数 
    A operator+(const A& a){ 
        return A(data + a.data);
    }   
private:
    int data;
};
int main(int ac, char *av[])
{
    A a1(100), a2(200);

    (a1+a2).show();
    return 0;
}

如我们所愿,进行如上更改我们完成了直接让两个类对象进行直接相加,大大减少了程序员的工作量。下来我们细细谈一下运算符重载函数的具体内容:

运算符重载函数的定义和调用分为两种:

1、以友元函数定义

定义格式: friend return_val   operatorOPT(type& name...);

调用格式:operatorOPT(obj_list);

obj1 OPT obj2;

友元不是成员,不能直接在友元函数中使用对象的成员变量,也不能使用this指针,所以在进行函数调用的时候,需要将对象的成员函数传进去。

2、以成员函数函数定义

定义格式:return_val   operatorOPT(type& name...);

注意:在使用成员函数进行调用的时候,如果使用对象的成员变量,不用将成员变量再传入函数中,直接在成员函数中使用就可以。

调用格式:obj1.operatorOPT(obj2);

obj1 OPT obj2;

下面举例来进行说明:

class F{
public:
    F(int n = 0, int d = 1):n(n), d(d){}
    // 以成员函数对操作符进行重载
    F operator*(const F& o)const{
        return F(o.n * n, o.d * d); 
    }  
    // 以友元函数对操作符进行重载,友元函数的声明 
    friend F operator/(const F& obj1, const F& obj2);
private:
    int n;
    int d;
};

// 友元函数的定义
F operator/(const F& obj1, const F& obj2)
{
    return(obj1.n * obj2.d, obj1.d * obj2.n);
}
int main(int ac, char *av[])
{
    F f1(1,2);
    F f2(3,4);
    F f3;
    
    f3 = f1.operator*(f2);
    f3.show();
    (f1*f2).show();
    f3 = operator/(f1, f2);
    f3.show();
    (f1/f2).show();
    
    return 0;
}

在进行运算符重载的时候我们需要注意两个问题:

1、在运算符的操作数,必须至少含有一个自定义类型的变量。

2、尽量使用成员函数对运算符进行重载,但是有的运算符只能使用友元函数进行重载。

比如对于"<<" 和“>>”的重载,如下:

class F{
public:
    F(int n = 0, int d = 1):n(n), d(d){}
    friend ostream& operator<<(ostream& os, const F& f){
        os << f.n << ‘/‘ << f.d;
        return os;
    }
    friend istream& operator>>(istream& is, F& f){
        char ch;
        is >> f.n >> ch >> f.d;
        return is;
    }
    F operator*(const F& o)const{
        return F(o.n * n, o.d * d);
    }
    friend F operator/(const F& obj1, const F& obj2);
private:
    int n;
    int d;
};

F operator/(const F& f1, const F& f2)
{
    return(f1.n * f2.d, f1.d * f2.n);
}
int main(int ac, char *av[])
{
    F f1(1,2);
    F f2(3,4);

    cout << f1 << "*" << f2 << "=" << f1*f2 << endl;
    cout << f1 << "/" << f2 << "=" << f1/f2 << endl;
    cout << "enter 2 number : \n";
    cin >> f1 >> f2;
    cout << "f1 = " << f1 << endl;
    cout << "f2 = " << f2 << endl;
    
    return 0;
}        
运行结果:
[[email protected] overload_operator]# ./muldiv
[1/2]*[3/4]=[3/8]
[1/2]/[3/4]=[4/6]
enter 2 number : 
123 / 456
234/ 7645
f1 = [123/456]
f2 = [234/7645]

以上的操作符全是对于双目运算符的重载,下面简单介绍几个单目运算符的例子,如"++"和"--"

因为++有前置++和后置++两种,--也是如此,对于前置++我们直接将++后的结果直接返回即可,对于后置++,为了方便区别于前置++,通常认为++后面仍然含有一个int类型的数组。进行如下操作:

class A{
public:
    A(int data = 0):data(data){}
    friend ostream& operator<<(ostream& os, const A& a){
        os << a.data;
        return os;
    }
    friend istream& operator>>(istream& is, A& a){
        is >> a.data;
        return is;
    }
    // 前置 ++;
    friend A& operator++(A& a){
         a.data += 10;
        return a;
    }
    // 前置 --
    A& operator--(){
        data -= 10;
        return *this;
    }
    // 后置 ++;
    friend A operator++(A& a, int){
        A old(a);
        a.data += 5;
        return old;
    }
    // 后置 --
    A operator--(int){
        A old(*this);
        data -= 5;
        return old;
    }
private:
    int data;
};
int main(int ac, char *av[])
{
    A a1(100);
    A a2(100);

    cout << "a1 = " << a1 << endl; 
    cout << "a2 = " << a2 << endl; 
    ++a1;
    --a2;
    cout << "++a1 = " << a1 << endl; 
    cout << "--a2 = " << a2 << endl; 
    cout << "a1++ = " << a1++ << endl; 
    cout << "a2-- = " << a2-- << endl; 
    cout << "a1 = " << a1 << endl; 
    cout << "a2 = " << a2 << endl; 
    return 0;
}

当然还有以下操作符不能进行重载:

1、三目运算符不能进行重载;

2、"."成员运算符不能重载;

3、成员指针运算符不能进行重载;

4、"::"这是对于类的运算符,不能进行重载。

================= 以上就是对于运算符重载的介绍 =======================

时间: 2024-12-10 03:51:58

细谈C++的运算符重载的相关文章

JAVA基础细谈

JAVA基础细谈 一. 源文件和编译后的类文件     源文件的本质就是程序文件,是程序员编写,是人看的.而编译后的类文件是给电脑看的文件.一个类就是一个文件,无论这个类写在哪里,编译以后都是一个文件.源文件通过java编译生成类文件,后缀名为”.java“的是源文件,后缀为“.class”的为类文件.如图 这就是一个源文件和一个和它同名的类文件,文件名和类名一样,方便开发中的文件管理. 二. 语句    java程序的组成是类文件,类文件的组成是方法,方法的组成语句.语句是任何程序的基本单位,

关于运算符重载

运算符重载需遵循以下原则: 1.除了类所属关系运算符".".成员指针运算符".*".作用域运算符"::".sizeof运算符.三目运算符"?:"之外,C++中所有的运算符都可以进行重载 2.重载运算符限制在C++已有的运算符范围内,不允许创建新的运算符 3.重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符的操作数的个数及语法结构 4.运算符重载不能改变运算符用于内置类型的对象的含义,只能用于自定义类型对象之间,

运算符重载

关键字:operator 相见:<高质量程序设计指南> P255 如果运算符被重载为全局函数,那么只有一个参数的运算符叫做一元运算符,有两个参数的运算符叫做二元运算符. 如果运算符被重载为类的成员函数,那么一元运算符没有参数(但是++和--运算符的后置版本除外),二元运算符只有右侧参数,因为对象自己成了左侧参数. 运算符重载的特殊性 如果重载为成员函数,则this对象发起对它的调用 如果重载为全局函数,则第一个参数发起对它的调用 禁止用户发明该语言运算符集合中不存在的运算符 除了函数调用运算符

C++ 运算符重载

C++中预定义的运算符的操作对象只能是基本数据类型,实际上,对于很多用户自定义类型,也需要有类似的运算操作.比如对象a和对象b, 那么 a+b 就需要用户自己定义它怎么相加,这时就用到了运算符重载. 运算符重载规则如下: ①. C++中的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已有的运算符. ②. 重载之后运算符的优先级和结合性都不会改变. ③. 运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造.一般来说,重载的功能应当与原有功能相类似,不能改变原运算符的操作对

Kotlin中复合赋值(+=,-=,……)运算符重载

本篇建立在已经了解了kotlin中运算符重载的理念以及如何实现的基础上. 来我们首先写一个简单的类,然后重载运算符+,+=,-,-=这个几个运算符.代码如下: data class Point(var x: Int, var y: Int) { operator fun plus(point: Point): Point { return Point(this.x + point.x, this.y + point.y) } operator fun plusAssign(point: Poin

第十章 运算符重载

第十章 运算符重载 1.运算符重载的方法 (实质:函数重载) *一般格式: 函数类型名operator 运算符名称(参数表){函数体:} 2.运算符重载的规则 *不允许定义新的运算符 *允许重载的运算符 双目运算符 +(加法)  - (减法)  * (乘法) / (除法)   %(取模) 关系运算符 ==(等于) != (不等)  <   >   <=   >= 逻辑运算符 ||(或)   && (与)  !(非) 单目运算符 + (正)  -(负)   *(指针)

C++运算符重载的妙用

运算符重载(Operator overloading)是C++重要特性之中的一个,本文通过列举标准库中的运算符重载实例,展示运算符重载在C++里的妙用.详细包含重载operator<<,operator>>支持cin,cout输入输出.重载operator[],实现下标运算.重载operator+=实现元素追加:重载operator()实现函数调用.假设你对C++的运算符重载掌握的游刃有余.那就无需继续往下看了. 运算符重载带来的优点就是--让代码变得简洁.以下将展示几个标准库因使

网易云课堂_C++开发入门到精通_章节4:运算符重载

课时23运算符重载 运算符重载 重载赋值运算符 Person& Person::operator=(const Person& other) { //检查自赋值 if (this == &other) { return *this; } //释放原有的内存资源 delete[]m_data; int length = strlen(other.m_data); m_data = new char[length + 1]; strcpy(m_data, other.m_data);

关于c++的运算符重载那些事

搞c++有一段时间了,今天突然要重载一个运算符,发现自己有点忘了,遂查查资料做一下c++运算符重载的小总结. 一.何为运算符重载 运算符的重载是c++语言特有的,java什么的是没有运算符重载的,所以运算符重载在笔试面试中有可能成为c++的高频考点.运算符重载就是重新定义运算符的意义,如常用的+,-,×,÷都是可以重载的.运算符重载使用的是关键字operator,表现形式是: