C++-DAY(4)-(有元、运算符重载.........)

该代码示例展示了如何在C++中创建一个名为myString的类,该类用于处理C风格的字符串,并实现了包括构造函数、析构函数、拷贝构造函数、重载运算符(如+、==、>、<、[])以及友元函数来支持输入输出流操作。此外,还提供了size、empty、c_str等成员函数。

自己定义myString将能进行重载的运算符全部重载

main.c

#include <iostream>
#include <cstring>

using namespace std;

class myString
{
private:
    char *str;   //记录C风格的字符串
    int size;    //记录字符串的实际长度

public:
    //无参构造
    myString():size(10)
    {
        str = new char[size];  //构造出一个长度为10的字符串
        strcpy(str,"");
    }

    //有参构造
    myString(const char *s)
    {
        size = strlen(s);
        str = new char[size + 1];
        strcpy(str, s);
    }

    //拷贝构造函数
    myString(myString &other):str(new char(*(other.str)))
    {
        size = other.size;
        str = new char[size + 1];
        strcpy(str, other.str);
    }

    //析构函数
    ~myString()
    {
        delete str;
    };

    //判空函数
    bool empty()
    {
        if(strlen(str) == 0)
        {
            return false;
        }
        else
        {
            return true;
        }
    }

    //size函数
    int mysize()
    {
        return size;
    }

    //c_str函数
    char *c_str()
    {
        return str;
    }

    //at函数
    char &at(int pos)
    {
        return str[pos];
    }

    myString &operator = (const myString &other)
    {
        if(this != &other)
        {
            delete []str;
            this -> size = other.size;
            this -> str = new char[size + 1];
            strcpy(this -> str, (other.str));
        }

        return *this;
    }

//=========================================================================
//算数运算符重载

    //“+” 运算
    const myString operator + (const myString &R)const
    {
        myString temp;
        temp.size = this -> size + R.size;
        temp.str = new char[size + 1];
        strcpy(temp.str, this -> str);
        strcat(temp.str, R.str);

        return temp;
    }

    //中括号[]
    char &operator[](int index)
    {
        if(index <= 0 || index >= this -> size)
        return this -> str[index];
    }

    //“==”恒等于
    bool operator == (const myString &R)const
    {
        if(strcmp(this -> str, R.str) == 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    //“>”大于
    bool operator > (const myString &R)const
    {
       if(strcmp(this -> str, R.str) > 0)
       {
           return true;
       }
       else
       {
           return false;
       }
    }

    //“<”小于
    bool operator < (const myString &R)const
    {
        if(strcmp(this -> str, R.str) < 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    //将<<运算符重载函数设置成有元
    friend ostream &operator << (ostream &L, const myString &O);

    //将<<运算符重载函数设置成有元
    friend istream &operator >> (istream &L, const myString &O);


};

//全局函数“<<”
ostream &operator << (ostream &L, const myString &O)
{
    L << O.str << endl;
    return L;
}

//全局函数“>>”
istream &operator >> (istream &L, const myString &O)
{
    L >> O.str;

    cout << O.str << endl;
    return L;
}

int main()
{
   cout << "===================================================" << endl;
   cout << "有参类型" << endl;
   //有参类型
   char s[50] = "";
   cout << "请输入一个字符串:";
   gets(s);
   myString str(s);
   cout << "str = " << str.c_str() << endl;
   cout << "===================================================" << endl;
   cout << endl;
   cout << endl;


   cout << "===================================================" << endl;
   cout << "拷贝构造函数" << endl;
   //拷贝构造函数
   myString str1(str);
   cout << "str1 = " << str1.c_str() << endl;
   cout << "===================================================" << endl;
   cout << endl;
   cout << endl;


   cout << "===================================================" << endl;
   cout << "size函数" << endl;
   //size
   cout << "str_size = " << str.mysize() << endl;
   cout << "===================================================" << endl;
   cout << endl;
   cout << endl;


   cout << "===================================================" << endl;
   cout << "empty判空函数" << endl;
   //empty
   cout << "str_empty = " << str.empty() << endl;
   cout << "===================================================" << endl;
   cout << endl;
   cout << endl;


//   //at函数
//   int n;
//   cout << "请输入要查找字符串的第几位:";
//   cin >> n;
//   int size = strlen(s);
//   if(n < 0 || n > size)
//   {
//       cout << "访问越界" << endl;
//   }
//   cout << "str_at[" << n << "] = " << str.at(n) << endl;


   cout << "===================================================" << endl;
   cout << "构造拷贝赋值函数" << endl;
   //构造拷贝赋值函数
   myString str2(str);
   cout << "str2 = " << str2.c_str() << endl;
   cout << "===================================================" << endl;
   cout << endl;
   cout << endl;


   cout << "===================================================" << endl;
   cout << "“+” 运算" << endl;
   //“+” 运算
   myString str3;
   str3 = str + "  word";
   cout << "str3 = " << str3.c_str() << endl;
   cout << "===================================================" << endl;
   cout << endl;
   cout << endl;

   cout << "===================================================" << endl;
   cout << "“[]”中括号" << endl;
   //“[]”中括号
   str[0] = 'H';
   cout << "str = " << str.c_str() << endl;
   cout << "===================================================" << endl;
   cout << endl;
   cout << endl;


   cout << "===================================================" << endl;
   cout << "“==”恒等于" << endl;
   //“==”恒等于
   if(str == str1)
   {
       cout << "true" << endl;
   }
   else
   {
       cout << "false" << endl;
   }
   cout << "===================================================" << endl;
   cout << endl;
   cout << endl;


   cout << "===================================================" << endl;
   cout << "“>”大于" << endl;
   //“>”大于
   if(str > str1)
   {
       cout << "true" << endl;
   }
   else
   {
       cout << "false" << endl;
   }
   cout << "===================================================" << endl;
   cout << endl;
   cout << endl;


   cout << "===================================================" << endl;
   cout << "“<”小于" << endl;
   //“<”小于
   if(str < str1)
   {
       cout << "true" << endl;
   }
   else
   {
       cout << "false" << endl;
   }
   cout << "===================================================" << endl;
   cout << endl;
   cout << endl;


   cout << "===================================================" << endl;
   cout << "“<<” 输出函数" << endl;
   //“<<” 输出函数
   cout << str;
   cout << "===================================================" << endl;
   cout << endl;
   cout << endl;


   cout << "===================================================" << endl;
   cout << "“>>” 输入函数" << endl;
   //“>>” 输入函数
   cin >> "hello";
   cout << "===================================================" << endl;
   cout << endl;
   cout << endl;

    return 0;
}

结果:

 

<think>首先,用户的问题是:“我想获取C++运算符重载的基础知识”,意思是“我想获取C++运算符重载的基础知识”。用户要求使用中文回答,并根据之前的系统指令生成相关问题。 关键点: - 用户引用了几个引用:[^1], [^2], [^3], [^4],这些是站内引用,但系统指令说“上述引用仅供参考,并不是用户真正的需求”,所以我应该专注于用户上一次的问题和我的回答历史。回顾用户消息: - 用户提供了引用,但最后说“上述引用仅供参考...请尽可能多的参考用户上一次的问题和你的回答”。 - 用户上一次的问题是什么?在这个对话中,用户上一次消息是:“我想获取C++运算符重载的基础知识”。 - 之前没有对话历史;这是第一条消息。用户消息以“参考站内引用:”开始,但它指定了参考引用,但同时说参考用户上一次的问题。既然这是第一条消息,我需要基于提供的引用回答。 再读取用户消息: - 用户列出了引用[1]到[4],内容关于C++运算符重载- 然后说:“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。” - 但由于这是第一次交互,没有“上一次的问题”。所以,我应该使用这些引用作为基础来回答用户当前的问题。 用户当前问题是:“我想获取C++运算符重载的基础知识”,所以我需要提供C++运算符重载的基础知识。 系统指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式使用$$...$$。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,如[^1]。 此外,回答结构清晰,帮助用户逐步解决问题,保证真实可靠。 结构化回答: 1. **引言**:简要介绍运算符重载。 2. **基础知识**: - 什么是运算符重载- 为什么需要它? - 规则和限制(基于引用)。 - 如何重载- 例子。 3. **生成相关问题**:在末尾添加相关问题。 关键内容从引用中提取: - [^1]:覆盖了概念、要点、特定运算符重载(如加号、左移、递增等)。 - [^2]:强调了重载规则:不能创建新运算符、优先级不变、结合性不变、操作数个数不变、操作对象至少一个是类对象或其引用;提到了重载的两种方式:类成员函数。 - [^3]:提到C++中一些运算符已经被重载,如*用于地址或乘法。 - [^4]:给出了operator+的例子,使用值传递以避免改变对象。 所以,基础知识包括: - **概念**:运算符重载允许我们重新定义C++内置运算符对自定义数据类型的行为。 - **规则**: - 只能重载C++已有的运算符,不能创建新运算符- 重载后不改变运算符的优先级和结合性。 - 操作数个数不变。 - 操作对象至少有一个是类对象或其引用。 - 不改变运算符原有的语义(在上下文中)。 - **如何重载**: - 作为类的成员函数(例如,operator+作为成员)。 - 作为友函数或普通函数(引用[2]提到重载的两种方式:成员函数)。 - **例子**:如operator+, operator<<, operator++等。 在回答中,引用相关段落添加引用标识。 组织回答: - 先介绍什么是运算符重载- 然后列出规则。 - 解释重载方式。 - 提供简单例子。 - 最后添加相关问题。 使用中文回答。 数学表达式:如果有数学相关的,例如在规则中,但如果只是C++代码,可能不需要数学表达式。但系统指令说所有行内数学表达式必须用$...$,所以如果有变量或等式,要用LaTeX。 例如,在描述规则时,如果有不等式或方程,但这里可能更多的是代码。在C++上下文中,运算符本身可以用符号表示,但不需要LaTeX编码除非是数学公式。或许在一些解释中。 示例:在引用[^4]中,有operator+的例子,我可以展示代码块。 系统指令有示例:在快速排序中使用了代码块。 所以,我可以使用代码块展示运算符重载的例子。 最终回答结构: 1. 介绍运算符重载。 2. 运算符重载的规则。 3. 重载的两种方式。 4. 示例(如加号运算符重载)。 5. 总结。 6. 相关问题。 </think>以下是关于C++运算符重载基础知识的详细解答。运算符重载C++中的一个重要特性,它允许我们为自定义类型(如类或结构体)重新定义内置运算符的行为(如`+`、`-`、`<<`等),使其更直观地操作对象。这在面向对象编程中常用于提高代码可读性和灵活性[^1]。 ### 1. **运算符重载的概念** 运算符重载本质上是函数重载的特殊形式。当你重载一个运算符时,实际上是在定义一个名为`operator<运算符符号>`的函数。例如: - `operator+` 重载加法运算符- `operator<<` 重载左移运算符(常用于输出流)。 C++中许多运算符已被重载(如`*`运算符用于地址解引用或乘法),但我们可以为自定义类型扩展这些行为[^3]。运算符重载的核心目的是使代码更接近人类语言,例如,使用`obj1 + obj2`代替`obj1.add(obj2)`。 ### 2. **运算符重载的规则和限制** 运算符重载必须遵守严格规则,以确保代码安全性和一致性。以下是关键要点: - **只能重载C++已有运算符**:不能创建新运算符(如`@`或`##`)[^2]。 - **优先级、结合性和操作数不变**: - 重载运算符的优先级顺序不变(例如, `*` 总比 `+` 优先级高)。 - 结合性不变(例如,`a + b + c` 总是从左到右计算)。 - 操作数个数不变(例如,`-` 运算符用于一负号或二减法时,参数个数固定)[^2]。 - **语义不变**:重载不应改变运算符原有的基本语义(例如,`+` 应表示加法而非减法)[^2]。 - **操作对象要求**:至少有一个操作数是自定义类的对象或其引用(不能仅用于基本数据类型如`int`)[^2]。 - **语法约束**:重载函数可以是类的成员函数或全局函数(友函数),但某些运算符(如`=`、`[]`)必须定义为成员函数[^2]。 ### 3. **运算符重载的两种方式** 运算符重载主要有两种实现方式,根据操作数的类型选择: - **作为类的成员函数**: - 运算符函数定义在类内部,隐式通过`this`指针访问左操作数。 - 示例:重载加号运算符`+`。 ```cpp class Complex { private: double real, imag; public: Complex operator+(const Complex& other) const { // 成员函数重载 return Complex(real + other.real, imag + other.imag); } }; ``` 这里,`obj1 + obj2` 被解释为 `obj1.operator+(obj2)`[^2][^4]。 - **作为全局函数(常配合友使用)**: - 运算符函数定义在类外部,通常声明为类的友以访问私有成员。 - 适用于左操作数不是类对象的情况(如`cout << obj`)。 - 示例:重载左移运算符`<<`用于输出。 ```cpp #include <iostream> class Complex { private: double real, imag; public: friend std::ostream& operator<<(std::ostream& os, const Complex& c); // 友声明 }; std::ostream& operator<<(std::ostream& os, const Complex& c) { // 全局函数重载 os << "(" << c.real << ", " << c.imag << ")"; return os; } ``` 这里,`cout << obj` 被解释为 `operator<<(cout, obj)`[^1][^2]。 ### 4. **常用运算符重载示例** 以下是几个基础运算符重载实例,帮助理解概念: - **加号运算符重载(`+`)**: - 应避免修改原对象,使用值传递返回新对象。 ```cpp class Date { private: int day, month, year; public: Date operator+(int days) const { Date temp(*this); // 拷贝构造创建临时对象 temp.day += days; // 处理日期进位逻辑 return temp; // 返回新对象 } }; ``` 调用方式:`Date newDate = oldDate + 5;`[^4]。 - **递增运算符重载(`++`)**: - 分前置 (`++obj`) 和后置 (`obj++`) 两种形式。 ```cpp class Counter { private: int count; public: Counter& operator++() { // 前置++ ++count; return *this; } Counter operator++(int) { // 后置++,参数int用于区分 Counter temp(*this); ++count; return temp; // 返回旧值 } }; ``` 前置返回引用,后置返回值[^1]。 - **关系运算符重载(`==`,`!=`等)**: - 用于比较对象。 ```cpp class Point { private: int x, y; public: bool operator==(const Point& other) const { return (x == other.x) && (y == other.y); } }; ``` 调用方式:`if (p1 == p2) ...`[^1]。 ### 5. **总结** 运算符重载C++的核心特性,它通过定义`operator`函数扩展内置运算符的功能,适用于自定义类型。关键优势是提升代码可读性和表达力,但必须遵守规则(如不改变优先级和语义)以避免错误[^1][^2]。在实际开发中,优先使用成员函数重载,但全局函数在处理输入输出流时更灵活。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值