运算符重载

C++提供了运算符重载的功能,对于我们自定义的类,使用运算符重载能够简化对像的操作。比如C++的string其实就使用了运算符重载功能,因此我们才能对其使用+==等操作。

不可重载的运算符:.::.*:?sizeof。其余运算符都是可重载的。但是,有些运算符的重载我们也很少使用,比如重载newdelete运算符,这可能给使用者造成困惑。

Java完全没有运算符重载,但是其类库却无比庞大,而且非常易用。可见,运算符重载并不是非用不可。但是适当的使用运算符重载确实能够简化代码,这里我们只介绍几个简单的运算符重载。

运算符重载的规则

  • 不能改变操作符的优先级和结合性
  • 不能改变操作符的操作数
  • 不能创建新的操作符,只能重载C++中已有的操作符,有些操作符不能重载

几个常用的运算符重载

下面例子重载了=操作符,允许直接将字符串字面值赋值给我们自定义的mystring类。

#include <iostream>
#include <cstring>

using namespace std;

class mystring
{
private:
    char *s;
public:
    mystring()
    {
        this->s = new char[1024];
    }

    mystring(const mystring &it)
    {
        this->s = new char[1024];
        strcpy(this->s, it.s);
    }

    void operator =(const char *s)
    {
        strcpy(this->s, s);
    }

    void print()
    {
        cout << this->s << endl;
    }

    ~mystring()
    {
        delete[] this->s;
    }
};

int main()
{
    mystring s1;
    s1 = "hello, world!";
    mystring s2 = s1;
    s2.print();

    return 0;
}

这里重载操作符的写法就是:void operator =(const char *s){},和定义一个函数差不多operator =其实就相当于函数名。

注意:mystring s2 = s1执行的其实是拷贝构造函数,定义为mystring(const mystring &it){},这里=原来的意义并没有改变,因为其参数类型是mystring &而不是const char *。实际上操作符重载的函数也是可以重载的。

下面例子重载了+运算符。实现了mystring之间相加,mystring和字符串字面值相加,字符串字面值和mystring相加三种功能。

#include <iostream>
#include <cstring>

using namespace std;

class mystring
{
private:
    char *s;
public:
    mystring()
    {
        this->s = new char[1024];
    }

    mystring(const char *s)
    {
        this->s = new char[1024];
        strcpy(this->s, s);
    }

    mystring(const mystring &it)
    {
        this->s = new char[1024];
        strcpy(this->s, it.s);
    }

    mystring operator +(mystring &it)
    {
        char buf[1024];
        strcpy(buf, this->s);
        strcat(buf, it.s);
        return buf;
    }

    mystring operator +(const char *s)
    {
        char buf[1024];
        strcpy(buf, this->s);
        strcat(buf, s);
        return buf;
    }

    void print()
    {
        cout << this->s << endl;
    }

    ~mystring()
    {
        delete[] this->s;
    }

    friend mystring operator +(const char *s, const mystring &m);
};

mystring operator +(const char *s, const mystring &m)
{
        char buf[1024];
        strcpy(buf, m.s);
        strcat(buf, s);
        return buf;
}

int main()
{
    mystring s1("hello");
    mystring s2("world");

    mystring s3 = s1 + s2;
    s3.print();

    mystring s4 = s1 + "aaa";
    s4.print();

    mystring s5 = "bbb" + s2;
    s5.print();

    return 0;
}

注意mystring operator +(const char *s, const mystring &m),这个是定义在类的外面的,但是它需要访问类内部的成员,因此类中声明了该函数为友元。

下面例子重载了==操作符。

#include <iostream>
#include <cstring>

using namespace std;

class mystring
{
private:
    char *s;
public:
    mystring()
    {
        this->s = new char[1024];
    }

    mystring(const char *s)
    {
        this->s = new char[1024];
        strcpy(this->s, s);
    }

    mystring(const mystring &it)
    {
        this->s = new char[1024];
        strcpy(this->s, it.s);
    }

    bool operator ==(const mystring &it)
    {
        if(strcmp(this->s, it.s) == 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    void print()
    {
        cout << this->s << endl;
    }

    ~mystring()
    {
        delete[] this->s;
    }

    friend bool operator ==(const mystring &s1, const mystring &s2);
};

bool operator ==(const mystring &s1, const mystring &s2)
{
    if(strcmp(s1.s, s2.s) == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

int main()
{
    mystring s1("hello");
    mystring s2("hello");

    if(s1 == s2)
    {
        cout << "true" << endl;
    }
    else
    {
        cout << "false" << endl;
    }

    return 0;
}

+的写法基本是相同的,注意重载==要求返回值是bool类型,这符合==的语意。

其余的操作符重载这里就不介绍了。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap