• 为什么有的操作符重载函数只能是成员函数?


    看c++面向对象高级开发的课时,操作符重载的问题。


    出自于c++ primer 5e的一句话:

    赋值(=)、下标([])、调用(())和成员访问箭头(->)运算符必须是成员(函数)。

    赋值运算符。

    我们知道一个c++类,程序员如果没有为其定义了赋值操作符重载函数,编译器也会隐式的定义,这样倘若再定义全局赋值运算符重载函数,将会发生二义性。即使编译器允许这样的定义手法,在调用的时候也编译不过:

    cls& operator=(cls& c1, const cls& c2)
    {
        //...
        return c1;
    }
    
    class cls
    {
    public:
        int m_a;
        char m_c;
    
        cls(int a, char c) : m_a(a), m_c(c) {}
    };
    
    int main(void)
    {
        cls c1(1, 2), c2(3, 4);
    
        c1 = c2;    //调用的是编译器隐式定义的operator=()还是程序员显示定义的全局的operator=()
    
        return 0;
    }

      操作符重载函数规定是类的成员函数,有一个至关重要的特点:类的this指针会被绑定到运算符的左侧运算对象,成员运算符函数的显示参数比运算符对象总数少一个。也就是说上文提到这些运算符的左操作数必须是该类类型的参数,换句话说,假设c++编译器允许[]操作符重载函数是全局的,那么程序员完全可以写出:

    cls& operator[](int dat, cls& c)
    {
        //...
        return c;
    }
    
    int main(void)
    {
        cls c(1, 'h');
        6[c];//c++编译器允许[]操作符重载函数是全局的
    
        return 0;
    }

      因为[]操作符重载函数是全局(友元)的,也就是没有了该函数的左操作数是this指针的限制,程序员可以任意定义左操作数的类型,类似的,就会出现6=c, 6(c), 6->c的代码,显然这样的代码是错误的。 
      不仅如此,假设cls类定义了转换构造函数

    cls::cls(int i);

      那么 operator的函数原型大可以是:

    cls& operator[](cls& c1, cls& c2)
    {
        //...
        return c1;
    }

      看似正确,但是若用户利用转换构造函数的隐式类型转换调用该函数:

    int main(void)
    {
        cls c(1, 'h');
        6[c];
    
        return 0;
    }

      同样编译通过,显然这还是错误的。因此,c++编译器对这些操作直接视为语法问题。


    string类的加号操作符重载函数

    另外我们可以推测string类的加号操作符重载函数是有两个版本的。如下正常运行的代码:

    std::string s1 = "hello";
    const char* s2 = "world";
    
    string s3 = s1 + "world";   
    string s4 = s2 + s1;

      代码中的两个加法操作分别执行成员函数

    string& operator+(const string& s);

        和友元全局函数

    string& opreator+(std::string s1, std::string& s2);

    因为假设二者都是调用成员函数的operator+(),那么第2个加法语句等价于

    s4 = s2.operator+(s1);

    然而s2是const char*类型,根本没有成员函数

  • 相关阅读:
    第一周、学习嵌入式
    centos7及xfce桌面环境安装,远程工具配置使用方法
    第一次作业
    2018下C语言基础课第1次作业
    第二次作业
    第一次作业
    第0次作业
    博客园第五次作业
    博客园第四次作业
    博客园第三次作业
  • 原文地址:https://www.cnblogs.com/lightmare/p/10398818.html
Copyright © 2020-2023  润新知