嵌入式C++(五)

一 运算符重载

1.1 概念

所谓重载,就是重新赋予运算符新的含义,运算符重载使得同一个运算符,具有不同的功能
运算符重载的本质就是函数的重载。
#include <iostream>
using namespace std;
class Complex
{
    //friend Complex operator+(const Complex &c1,const Complex &c2);
    private:
        int a;  //实部
        int b;  //虚部
    public:
        Complex(int _a,int _b)
        {
            this->a = _a;
            this->b = _b;
        }
        void print()
        {
            cout<<a<<"+"<<b<<"i"<<endl;
        }
       Complex operator+(const Complex &c)
       {
            Complex t(0,0);
            t.a = this->a + c.a;
            t.b = this->b + c.b;
            return t;
       }
};
/*Complex operator+(const Complex &c1,const Complex &c2)
{
    Complex t(0,0);
    t.a = c1.a + c2.a;
    t.b = c1.b + c2.b;
    return t;
}*/
int main(int argc, char const *argv[])
{
    Complex c1(1,2);
    Complex c2(2,3);
    Complex c(0,0);
    c = c1 + c2;  //c = c1.operator+(c2);
    c.print();
    return 0;
}

1.2 运算符重载的规则

(1)不能重载的运算符

:: ?: . .* sizeof

(2) 重载不能改变运算符的优先级和结合性

c4 = c1 + c2 * c3;
等价于:c4 = c1 + (c2 * c3);

(3) 重载不能概念运算符的用法(即不能改变其操作数)

(4) 运算符重载不能有默认参数,否则会改变运算符的操作数

1.3 重载的步骤

1.写出函数名称。
2.根据操作数写出函数的形参。
3.根据使用场景写出函数的返回值类型。
4.完成函数体。

1.4 重载输出运算符

#include <iostream>
using namespace std;
class Complex
{
    friend ostream& operator<<(ostream &out,const Complex &c);
    //friend Complex operator+(const Complex &c1,const Complex &c2);
    private:
        int a;  //实部
        int b;  //虚部
    public:
        Complex(int _a,int _b)
        {
            this->a = _a;
            this->b = _b;
        }
        void print()
        {
            cout<<a<<"+"<<b<<"i"<<endl;
        }
       Complex operator+(const Complex &c)
       {
            Complex t(0,0);
            t.a = this->a + c.a;
            t.b = this->b + c.b;
            return t;
       }
       /*ostream& operator<<(ostream &out)
       {
            out<<this->a<<"+"<<this->b<<"i";
            return out;
       }*/
};
ostream& operator<<(ostream &out,const Complex &c)
{
    out<<c.a<<"+"<<c.b<<"i";
    return out;
}
int main(int argc, char const *argv[])
{ 
    Complex c1(1,2);
    //c1.print();
    cout<<c1<<endl;  //operator<<(operator<<(cout,c1),endl);
    return 0;
}

1.5 单目运算符的重载

++ --
#include <iostream>
using namespace std;
class Complex
{
    friend ostream& operator<<(ostream &out,const Complex &c);
    //friend Complex operator+(const Complex &c1,const Complex &c2);
    private:
        int a;  //实部
        int b;  //虚部
    public:
        Complex(int _a,int _b)
        {
            this->a = _a;
            this->b = _b;
        }
        void print()
        {
            cout<<a<<"+"<<b<<"i"<<endl;
        }
        Complex operator+(const Complex &c)
        {
            Complex t(0,0);
            t.a = this->a + c.a;
            t.b = this->b + c.b;
            return t;
        }
        //前置++
        Complex operator++()
        {
            this->a++;
            this->b++;
            return *this;
        }
        //后置++
        Complex operator++(int)  //通过占位参数来构成函数重载
        {
            Complex t = *this;
            this->a++;
            this->b++;
            return t;
        }
       /*ostream& operator<<(ostream &out)
       {
            out<<this->a<<"+"<<this->b<<"i";
            return out;
       }*/
};
ostream& operator<<(ostream &out,const Complex &c)
{
    out<<c.a<<"+"<<c.b<<"i";
    return out;
}
int main(int argc, char const *argv[])
{
    Complex c1(1,2);
    cout<<++c1<<endl;
    cout<<c1++<<endl;
    cout<<c1<<endl;
    return 0;
}

1.6 逻辑运算符的重载

&&: c1 && c2
||: c1 || c2

#include <iostream>
using namespace std;
class Complex
{
    friend ostream& operator<<(ostream &out,const Complex &c);
    //friend Complex operator+(const Complex &c1,const Complex &c2);
    private:
        int a;  //实部
        int b;  //虚部
    public:
        Complex(int _a,int _b)
        {
            this->a = _a;
            this->b = _b;
        }
        void print()
        {
            cout<<a<<"+"<<b<<"i"<<endl;
        }
        Complex operator+(const Complex &c)
        {
            Complex t(0,0);
            t.a = this->a + c.a;
            t.b = this->b + c.b;
            return t;
        }
        //前置++
        Complex operator++()
        {
            this->a++;
            this->b++;
            return *this;
        }
        //后置++
        Complex operator++(int)  //通过占位参数来构成函数重载
        {
            Complex t = *this;
            this->a++;
            this->b++;
            return t;
        }
        bool operator&&(const Complex &c)
        {
            
        }
       /*ostream& operator<<(ostream &out)
       {
            out<<this->a<<"+"<<this->b<<"i";
            return out;
       }*/
};
ostream& operator<<(ostream &out,const Complex &c)
{
    out<<c.a<<"+"<<c.b<<"i";
    return out;
}
int main(int argc, char const *argv[])
{
    Complex c1(1,1);
    Complex c2(2,2);
    Complex c3(0,0);
    if(c1 && c2)
    {
        cout<<"成立"<<endl;
    }
    if(c3 && c1++ +c2++)  //operator&&(c3,operator+(c1,c2))  //重载的时候不要重载逻辑运算符&& ||,因为违背了短路原则
    {
        
    }
    return 0;
}

1.7 数组类

#include <iostream>
using namespace std;
class Array
{
    private:
        int size;
        int *data;
    public:
        Array(int s)
        {
            size = s;
            data = new int[size];
        }
        int& operator[](int Index)
        {
            return data[Index];
        }
        bool operator==(const Array &a)
        {
            /*
            if(this->size != a.size)
            {
                return false;
            }
            for(int i = 0; i < size;i++)
            {
                if(this->data[i] != a.data[i])
                {
                    return false;
                }
            }
            return true;
            */
           return (this->data == a.data && this->size == a.size);
        }
        Array& operator=(const Array &a)
        {
            if(*this == a)
            {
                return *this;
            }
            /*if(this == &a)
            {
                return *this;
            }*/
            this->size = a.size;
            delete this->data;
            this->data = new int[size];
            for(int i = 0; i< size;i++)
            {
                this->data[i] = a.data[i];
            }
        }
        ~Array()
        {
            if(data != NULL)
            {
                delete []data;
            }
        }
};

int main(int argc, char const *argv[])
{
    Array a1(10);  //创建数组对象
    a1[0] = 100;
    for(int i = 0; i < 10;i++)
    {
        a1[i] = i + 10;
    }
    for(int i = 0; i < 10;i++)
    {
        cout<<a1[i]<<" ";
    }
    cout<<endl;

    Array a2(5);
    //a1 = a2;
    a1 = a1;
    for(int i = 0 ; i< 10;i++)
    {
        cout<<a1[i]<<" ";
    }
    cout<<endl;
    return 0;
}

练习:自己实现string类(字符串类)

#include <iostream>
#include <cstring>
using namespace std;
class MyString
{
    public:
        MyString();
        MyString(const char *str);
        MyString(const MyString &obj);
        char& operator[](int index);
        MyString& operator=(const char *str);
        MyString& operator+(const char *str);
        MyString& operator+(const MyString &str);
        bool operator==(const MyString &obj);
        void show();
    private:
        char *pstring;
        int m_size;
};
void MyString::show()
{
    cout<<"string = "<<pstring<<endl;
}
MyString::MyString()
{
    this->m_size = 0;
    this->pstring = NULL;
}
MyString::MyString(const char *str)
{
    m_size = strlen(str) + 1;
    this->pstring = new char[m_size];
    strcpy(this->pstring,str);
}
MyString::MyString(const MyString &obj)
{
    this->m_size = obj.m_size;
    this->pstring = new char[m_size];
    strcpy(this->pstring,obj.pstring);
}
char& MyString::operator[](int index)
{
    static char ch =-1;
    if(index >=0 && index < this->m_size)
    {
        return this->pstring[index];
    }
    else
    {
        printf("越界操作了\n");
        return ch;
    }
}
MyString& MyString::operator=(const char *str)
{
    this->m_size = strlen(str) + 1;
    if(this->pstring != NULL)
    {
        delete []this->pstring;
        this->pstring = new char[m_size];
    }
    else
    {
        this->pstring = new char[m_size];
    }
    strcpy(this->pstring,str);
    return *this;
}
MyString& MyString::operator+(const char *str)
{
    if(this->pstring != NULL)
    {
        char *s = new char[this->m_size + 1];
        strcpy(s,this->pstring);
        delete []this->pstring;
        this->pstring = new char[this->m_size + strlen(str) + 1];
        stpcpy(this->pstring,s);
        strcat(this->pstring,str);
        this->m_size += strlen(str);
        delete []s;
    }
    else
    {
        this->pstring = new char[strlen(str) + 1];
        this->m_size = strlen(str);
        strcpy(this->pstring,str);
    }
    return *this;
}
MyString& MyString::operator+(const MyString &str)
{
    if(this->pstring != NULL)
    {
        char *s = new char[this->m_size + 1];
        strcpy(s,this->pstring);
        delete []this->pstring;
        this->pstring = new char[this->m_size + str.m_size + 1];
        stpcpy(this->pstring,s);
        strcat(this->pstring,str.pstring);
        this->m_size += str.m_size;
        delete []s;
    }
    else
    {
        this->pstring = new char[str.m_size + 1];
        this->m_size = str.m_size;
        strcpy(this->pstring,str.pstring);
    }
    return *this;
}
bool MyString::operator==(const MyString &obj)
{
    if(strcmp(this->pstring,obj.pstring) == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}
int main(int argc, char const *argv[])
{
    MyString m1("hello world");
    m1.show();
    MyString m2(m1);
    m2.show();

    cout<<m2[3]<<endl;
    cout<<m2[0]<<endl;

    m2 = "nihao beijing";
    m2.show();

    MyString m3;
    m3 = m2 = m1;
    m1.show();
    m2.show();
    m3.show();

    cout<<"***************"<<endl;
    MyString m4("nihao");
    m4 = m4 + "helloworld";
    m4.show();

    MyString m5("hahahah");
    m5 = m5 + m4;
    m5.show();

    if(m5 == m4)
    {
        cout<<"m5 = m4"<<endl;
    }
    else
    {
        cout<<"m5 != m4"<<endl;
    }

    return 0;
}

二 模板

泛型编程,通过建立一个通用的函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来表示,这个通用的函数就是函数模板。

2.1 函数模板

template <类型形式参数表>
类型 函数名<形式参数表>
{
	语句块
}
#include <iostream>
using namespace std;
/*int add(int x,int y)  //int y = 'a'
{
    cout<<"int add(int x,int y)"<<endl;
    return x + y;
}
double add(double x,double y)
{
    cout<<"double add(double x,double y)"<<endl;
    return x + y;
}*/

template <typename T>
T add (T x, T y)
{
    cout<<"T add (T x, T y)"<<endl;
    return x + y;
}

template<typename T1,typename T2>
void print(T1 x,T2 y)
{
    cout<<x<<" "<<y<<endl;
}
int main(int argc, char const *argv[])
{
    cout<<add(1,2)<<endl;  //隐式调用
                            //当模板函数和普通函数同时存在,优先调用普通函数

    cout<<add<int>(1,'a')<<endl;//显示调用  
                                //模板函数不能进行隐式类型转换
    print(1,'a');
    print<double,char>(1.11,'a');
    return 0;
}

2.2 函数模板的实现机制

实现机制:二次编译/延迟编译:第一次看到模板函数定义的位置时,编译时只检查基本语法错误,不检查数据类型的错误,使用模板函数实例化对象时,看到模板函数之后根据传递的模板实参再检查类型的错误,这种编译方法称为二次编译。

笔试题

#include <stdio.h>

struct test{
	int a;
	int b;
};
void func(struct test *tt)
{
    struct test *lt;
    lt = &tt[0];
    printf("[0]a:%d,b: %d\n",lt->a,lt->b);
    lt = &tt[1];
    printf("[1]a:%d,b: %d\n",lt->a,lt->b);
    lt = &tt[2];
    printf("[2]a:%d,b: %d\n",lt->a,lt->b);
    
}
/*
void func(struct test *tt,int length)
{
    int i;
    struct test *lt;
    for(i = 0 ; i < length;i++)
    {
        lt = &tt[i];
        printf("[%d]a:%d,b: %d\n",i,lt->a,lt->b);
    }
    /*printf("[0]a:%d,b: %d\n",lt->a,lt->b);
    lt = &tt[1];
    printf("[1]a:%d,b: %d\n",lt->a,lt->b);
    lt = &tt[2];
    printf("[2]a:%d,b: %d\n",lt->a,lt->b);*/
    return;
}
*/
int main()
{
    struct test lm[3] = {{1,2},{11,22},{111,222}};
    struct test llm = {333,444};
    func(lm);
    func(&llm);
}
posted @ 2022-07-11 19:10  周末不下雨  阅读(14)  评论(0编辑  收藏  举报