美文网首页
C++ 学习(3) ---- 运算符重载和赋值构造

C++ 学习(3) ---- 运算符重载和赋值构造

作者: 特立独行的佩奇 | 来源:发表于2023-02-26 21:34 被阅读0次

    C++ 运算符重载

    运算符重载的本质还是函数重载,可以将运算符理解为特殊的函数名:

    • 运算符重载时,运算顺序和优先级不变,操作数个数不变
    • 不能创造新的操作符,并且规定下面的六个操作符不能重载
    • 运算符重载函数不能有默认的参数
    • 重载函数既可以作为类的成员函数,也可以作为全局函数(一般定义为友元函数)

    箭头运算符->、下标运算符[ ]、函数调用运算符( )、赋值运算符= 只能以成员函数的形式重载

    不可重载的运算符.jpg

    可以重载的运算符基本可以分为:


    可以重载的运算符.jpg
    赋值运算符重载

    只能以成员函数的形式重载,基本形式为:基本形式为 classname& operator=(classname& 实例对象)
    注意输入参数只有一个,而且必须是对象的引用,返回值也必须是对象的引用
    tips:可以将operator= 看成一个整体,当成函数名,赋值运算符重载函数也可以重载,即可以有多个

    //声明
    allOperatorDemo& operator=(allOperatorDemo& p);
    allOperatorDemo& operator=(string str);
    
    //定义
    allOperatorDemo& allOperatorDemo::operator=(allOperatorDemo& p) {
        mstr = p.mstr;
        return *this;
    }
    
    allOperatorDemo& allOperatorDemo::operator=(string str) {
        mstr = str;
        mstr.append("=string_str");
        return *this;
    }
    
    //使用
    // 赋值运算符重载
    {
        allOperatorDemo p("init");
        p = "hello";
        cout << "p mstr: " << p.mstr << endl; // hello=string_str 
    
        allOperatorDemo q("demo");
        p = q;
    
        cout << "p mstr: " << p.mstr << endl; // demo
    }
    
    算术运算符重载

    算术运算符包括+、++、–、- -、+=、-=、/、*等,作为成员函数重载的基本形式为:
    classname& operator运算符(classname& 实例对象)
    除了自增和自减运算符,其余算术运算符都是一个参数,返回值是对象的引用

    • 全局运算符重载
      friend classname& operator运算符(const classname& a,const classname& b)
    • 成员函数重载
      classname& operator运算符(const classname& b)

    tips: 运算符重载的参数可以任意定义,但是不能改变参数的个数

    //声明
    allOperatorDemo& operator+(allOperatorDemo& p);
    allOperatorDemo& operator+(const char* str);
    allOperatorDemo& operator-(allOperatorDemo& p);
    allOperatorDemo& operator*(allOperatorDemo& p);
    allOperatorDemo& operator/(allOperatorDemo& p);
    
    allOperatorDemo& operator+=(allOperatorDemo& p);
    allOperatorDemo& operator-=(allOperatorDemo& p);
    allOperatorDemo& operator*=(allOperatorDemo& p);
    allOperatorDemo& operator/=(allOperatorDemo& p);
    
    //定义
    allOperatorDemo& allOperatorDemo::operator+(allOperatorDemo& p) {
        mstr.append(p.mstr);
        return *this;
    }
    
    allOperatorDemo& allOperatorDemo::operator+(const char* str) {
        mstr.append(str).append("operator+_const_str");
        return *this;
    }
    
    allOperatorDemo& allOperatorDemo::operator-(allOperatorDemo& p) {
        mstr.append("operator-");
        return *this;
    }
    
    allOperatorDemo& allOperatorDemo::operator*(allOperatorDemo& p) {
        mstr.append("operator*");
        return *this;
    }
    
    .... //其余形式相同
    
    

    注意算术运算符+,-,*,/ 的两种调用形式的区别

    allOperatorDemo democ = demoa + demob  和
    
    allOperatorDemo democ;
    democ = demoa + demob;
    

    第一种只会调用到 + 运算符重载,第二种先实例化了对象,会同时调用到赋值运算符和 + 运算符重载

    调用形式如下:

    // 算术运算符重载
    {
        allOperatorDemo p("init");
        allOperatorDemo m("demo");
    
        //allOperatorDemo q = p + "hello";
        allOperatorDemo q = p + m;
        cout << "p mstr: " << p.mstr << endl; //p mstr: initdemo
    
    }
    
    {
        allOperatorDemo p("init");
        allOperatorDemo m("m");
        p += m;
        cout << "p mstr: " << p.mstr << endl; // p mstr: initoperator+=
    }
    

    +,-,*,/ 重载函数调用完成之后,两个输入对象作为参数,本身没有发生变化

    注意使用 +=,-= 等也属于赋值运算符,只能定义为成员函数

    关系运算符重载
    bool operator>(allOperatorDemo& p);
    bool operator>(const char* str);
    bool operator>=(allOperatorDemo& p);
    bool operator<(allOperatorDemo& p);
    bool operator<=(allOperatorDemo& p);
    bool operator==(allOperatorDemo& p);
    bool operator!=(allOperatorDemo& p);
    
    bool allOperatorDemo::operator>(allOperatorDemo& p) {
        return (mstr > p.mstr ? true : false);
    }
    
    bool allOperatorDemo::operator>(const char* str) {
    return (mstr > str ? true : false);
    }
    
    
    bool allOperatorDemo::operator>=(allOperatorDemo& p) {
    return (mstr >= p.mstr ? true : false);
    }
    

    关系运算符重载函数也是可以重载的,比如上面对 > 运算符的重载
    调用形式:

    // 关系运算符重载
    {
        allOperatorDemo p("init");
        allOperatorDemo m("thismorning");
    
        cout << "p(init) > m(this morning) " << (p > m) << endl;
        cout << "p(init) >= m(this morning) " << (p >= m) << endl;
        cout << "p(init) < m(this morning) " << (p < m) << endl;
        cout << "p(init) <= m(this morning) " << (p <= m) << endl;
        cout << "p(init) == m(this morning) " << (p == m) << endl;
        cout << "p(init) != m(this morning) " << (p != m) << endl;
    }
    
    自增自减运算符重载

    对于 p++ 和 ++p 这两种形式都是可以重载的,operator++(int) 对应于 p++这种形式,:operator++()对应于++p 这种形式

    allOperatorDemo& operator++();
    allOperatorDemo& operator++(int);
    allOperatorDemo& operator--();
    allOperatorDemo& operator--(int);
    
    allOperatorDemo& allOperatorDemo::operator++() {
    mstr.append("operator++");
    return *this;
    }
    
    allOperatorDemo& allOperatorDemo::operator++(int) {
    mstr.append("operator++_int");
    return *this;
    }
    
    数组下标[ ] 运算符重载

    只能以成员函数的形式重载

    char operator[](uint32_t pos);
    void operator[](string str);
    
    char allOperatorDemo::operator[](uint32_t pos) {
    return mstr[pos];
    }
    
    
    void allOperatorDemo::operator[](string str) {
    mstr.append("[]_string_str");
    }
    
    {
        allOperatorDemo p("init");
        char c = p[2];
        cout << "p[2]: " << c << endl; //p[2]: i
    
        p["hello"];
        cout << "p mstr: " << p.mstr << endl; //p mstr: init[]_string_str
    }
    

    赋值构造函数

    赋值构造函数(Assignment Constructor)是一种特殊的构造函数,用于将一个已存在的对象的值赋给另一个对象;赋值构造函数通常用于实现对象的赋值语句
    demoClass p;
    demoClass q = p;

    需要注意的是,赋值构造函数与拷贝构造函数不同,拷贝构造函数用于将一个对象的值复制到另一个对象中,而赋值构造函数用于将一个已存在的对象的值赋给另一个对象

    赋值构造函数的原型与拷贝构造函数类似,但是它使用赋值运算符(=)来初始化一个对象,例如:

    demoClass& operator=(const demoClass& obj)
    

    如果一个类没有显式定义赋值构造函数,编译器会生成一个默认的赋值构造函数,但是这个默认的构造函数只是进行浅拷贝(也就是仅仅复制指针或者成员变量的值),这可能会导致对象之间的数据共享或者内存泄漏问题,因此在需要复制对象时,建议自行实现赋值构造函数

    赋值构造函数和拷贝构造函数的区别:

    1. 拷贝构造函数是构造函数的一种,它没有返回值,在创建新对象的时候如果使用下面的形式定义对象,拷贝构造函数会被自动调用到
      newkeyWordDemo p(10);
      newkeyWordDemo q(p);

    2. 赋值构造函数是 = 操作符的一种重载实现,参数是一个常量引用,返回值是对象的引用
      newkeyWordDemo p(10);
      newkeyWordDemo q = p;

    相关文章

      网友评论

          本文标题:C++ 学习(3) ---- 运算符重载和赋值构造

          本文链接:https://www.haomeiwen.com/subject/ojicldtx.html