C++ 函数重载、操作符重载

发布时间:2023年12月19日

依然是温故而知新,不过现在更多的是以此为乐的心态啦。本篇通过代码实例,展示c++函数重载相关知识,包括构造函数的重载、操作符重载等。
在构造函数重载中,给大家带来点稍微提升的用法, 看了不吃亏,看了不上当
鞭策下面的代码吧,以后在某些场景上SHOW一把时,你可能用的上。

#include <iostream>
#include <assert.h>
#include <sal.h>
#include <string>
#include <vector>

using namespace std;

 知识点
 do{ statement; }while(0) 经常用在宏定义中,减少一些错误的发生
//
#ifdef MYTRACE()
#else
#define MYTRACE() do { std::cout << __FUNCTION__ << ",line" << __LINE__ << std::endl;}while(0)
#endif


class Student
{
public:
    /// construct
    Student(){MYTRACE();}
    Student( _In_ const std::string name):m_name(name){MYTRACE();}
    Student(const std::string name,const int age):m_name(name),m_age(age){MYTRACE();}

    /// copy construct
    Student( _In_ const Student& that){
        this->m_age = that.m_age;
        this->m_name = that.m_name;
        MYTRACE();
    }

    /// 拷贝赋值
    Student& operator=(const Student& that){
        if(this == &that){
            return *this;
        }
        this->m_age = that.m_age;
        this->m_name = that.m_name;
        return *this;
    }

    /// 操作符重载
    friend ostream& operator <<(ostream& out,const Student& that){
        return out << that.m_name << " is " << that.m_age << " years old.";
    }

    bool operator !=(const Student& that){
        return !(that.age() == this->m_age && that.name() == this->m_name);
    }

    bool operator ==(const Student& that){
        return that.age() == this->m_age && that.name() == this->m_name;
    }
    
    /// 常成员函数
    const int age() const { return m_age;}
    const std::string name() const { return m_name;}

private:
    int m_age = 0;
    std::string m_name;
};

Student 中我们使用了C++中的一些基础知识,只能说中规中矩,平平无奇。

class StudentList
{
public:

    /*********************construct*******************/
    StudentList(){}
    StudentList(std::vector<Student> l):m_sl(l){}

    StudentList(const Student& t){  m_sl.push_back(t); }
    StudentList(const Student&& t){ m_sl.push_back(t); }

    /// 禁用拷贝构造和拷贝赋值
    StudentList(const StudentList& that) = delete;
    void operator =(const StudentList& that) = delete;


    /// 玩点儿高级的:参数列表构造
    void append(const Student& t){ m_sl.push_back(t); }

    template <typename ...Args>
    void append(const Student& t, const Args&... args) {
        m_sl.push_back(t);
        append(args...);    // 递归
    }

    template <typename ...Args>
    StudentList(const Student& t,const Args&... args){ append(t,args...);}

    /// 流式构造
    StudentList& operator<<(const Student& t) { append(t); return *this; }

    /*********************construct*******************/

    const std::vector<Student>& data() const{return m_sl;}

    /******************************* 操作符重载 ************************/
    friend ostream& operator <<(ostream& out,const StudentList& that){
        for (const auto& v : that.data()) { out << "(" << v.name() << "," << v.age() << ")" ; }
        return out;
    }

    const Student& operator []( _In_  const unsigned& index)const {
        assert(index < m_sl.size());
        return m_sl[index];
    }

    const Student& at(_In_ const unsigned& index) const { return m_sl[index];}

    bool operator !=(const StudentList& that)
    {
        if(this == &that){return false;}

        if(this->data().size() == that.data().size())
        {
            for(unsigned i = 0; i < that.data().size();++i){
                if( const_cast<Student&>(this->data()[i])
                        !=  const_cast<Student&>(that.data()[i])){
                    return true;
                }
            }
        }
        return true;
    }

    bool operator ==(const StudentList& that){
        return !(const_cast<StudentList&>(that) != const_cast<StudentList&>(*this));
    }


    /// 这里不做去重处理
    StudentList& operator +=(const StudentList& that)
    {
        for(auto v : that.data()){
            append(v);
        }
        return *this;
    }

    /******************************* 操作符重载 ************************/


private:
    std::vector<Student> m_sl;
};

StudentList 类中我们做了一些有意思的尝试,譬如让StudentList支持参数列表的初始化,这让他看起来显然cool了一些,其次我们通过重载 operator << 操作符,增加了支持流式的操作。这类似Qt中的

QStringList() << "wo" << "miss" << "u";

是不是瞬间高大上了一些呢。有点像写文章时堆砌的华丽辞藻?显然不是,一些高级语法的应用,其实只是为了让我们的程序更加优雅,更健壮~

int main()
{
    /// 测试重载的Student构造函数
    Student st1;
    Student st2("LiLei",25);
    Student st3("Keke",26);

    /// 测试拷贝构造函数
    Student st4(st3);
    std::cout << st4 << std::endl;

    st4 = st2;
    std::cout << st4 << std::endl;


    /// list类型参数 构造函数
    StudentList sl(std::vector<Student>{st2,st3,st4});
    std::cout << sl << std::endl;


    /// 参数列表 递归构造函数
    StudentList sl1{st2,st3,st4,Student("zhanglu",24)};
    std::cout << sl1 << std::endl;


    /// 流式构造
    StudentList sl2;
    sl2 << st2 << st3 << st4 << Student("zhaoya",25) << Student("lixiu",25);
    std::cout << sl2 << std::endl;

    // 测试使用下标重载函数
    std::cout << sl2[1] << std::endl;
    std::cout << sl2.at(0) << "   " << sl2.at(1) << std::endl;
    // std::cout << sl2[6] << std::endl; // error


    // 测试 != 和 == 操作符
    std::string sflag = (sl2 != sl2) ? "true" : "false";
    std::cout <<  sflag << std::endl;

    sflag = (sl2 == sl2) ? "true" : "false";
    std::cout <<  sflag << std::endl;

    sflag = (sl2 != sl1) ? "true" : "false";
    std::cout <<  sflag << std::endl;


    // 测试 "+" 操作符
    StudentList sl3{Student("xiaoli",25)};
    sl3 += sl2;
    std::cout <<  sl3 << std::endl;

    return 0;
}

ok,有兴趣你也动手试试吧~
每日几行代码 + 一瓶劲酒,祝吾早日登(升)天
请添加图片描述

文章来源:https://blog.csdn.net/weixin_39568531/article/details/135088101
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。