<C++>运算符重载进阶之左移运算符,输出成员属性一步到位

简介: <C++>运算符重载进阶之左移运算符,输出成员属性一步到位

左移运算符


形如"<<"


定义


       C++中左移运算符就是标准的一个输出流类创建的一个输出流对象,通俗点是"cout<<"后的合法内容会被输出到终端并显示。


目的


       解决直接输出类成员属性的问题:通过重载左移运算符一次性输出成员的属性。


详解重载过程


       函数名用编译器提供的operator<<


具体形式


学生类示例:


class Student
{
  friend ostream &operator<<(ostream& out, Student& s);
public:
  Student(int h, int w)
  {
    this->s_hight = h;
    this->s_weight = w;
  }
private:
  int s_hight;
  int s_weight;
};

       这个学生类有两个私有属性身高和体重以及一个有参构造方法来给私有属性赋值,然后开头是一个友元的声明,目的是让重载的运算符可以访问身高和体重这两个私有属性,不理解friend关键字的朋友们可以看看我端午节发的关于C++的友元知识🎉友元的所有形式🎉



       类比上次的加号运算符重载,左移运算符重载应该可以有两种方式,即成员函数实现和全局函数实现,但是成员函数是不常用的,看接下来的解释。


不建议成员函数实现

ostream& operator<<(ostream& cout)
  {
    cout << "该学生身高为:"<< this->s_hight;
    cout << "该学生体重为:"<< this->s_weight;
    return cout;
  }


调用形式:


void test1()
{
  Student S1(180, 130);
  S1 << cout<<"\nHello World";
}


       这个是可以运行的,但是看着太别扭了,由于是成员函数,需要用对象调用该函数,那么对象就得写前面,要是自己看还好,要是给别人看还不得被笑死 ,所以我很不推荐用成员函数实现左移的重载,至于重载的函数为什么这样写,在我下面展示完全局函数实现重载的时候会一一详解,往下看。


全局函数实现

ostream &operator<<(ostream &out, Student& s)
{
  out << "该学生身高为:" << s.s_hight << "\t该学生体重为:" << s.s_weight ;
  return out;
}


调用形式:


void test()
{
  Student S(182, 140);
  cout << S << "\t还没结束" << endl;
}


       重载的函数名是operator<<,传入的参数是ostream &cout Student &s,返回值类型也是ostream &cout ,其实ostream cout的类型,而cout又代表着标准输出流,我们可以这样看:在编译器找到cout,右键后选择速览定义,效果如下:


image.png


       可以看到cout的定义是ostream类 ,cout是标准输出类的对象,这是静态地址,所以我们传参的时候要传入引用,以免产生副本;而且返回的时候也要返回该对象的引用形式,不然返回的地址不一样,而对象值作为返回值会调用拷贝构造函数在新的地址生成新的cout,这是肯定行不通的。因此返回值和参数都采用标准输出类的对象引用,而且这样符合链式编程的特点。可以不断增加"<<"来增加输出的内容。


运行效果:


image.png

相关文章
|
29天前
|
存储 算法 搜索推荐
【C++】类的默认成员函数
【C++】类的默认成员函数
|
7天前
|
C++
C++(十五) 运算符重载
C++中的运算符重载允许对已有运算符的功能进行重新定义,从而扩展语言功能、简化代码并提升效率。重载遵循特定语法,如 `friend 类名 operator 运算符(参数)`。重载时需注意不可新增或改变运算符数量、语义、优先级、结合性和返回类型。常见示例包括双目运算符 `+=` 和单目运算符 `-` 及 `++`。输入输出流运算符 `&lt;&lt;` 和 `&gt;&gt;` 也可重载。部分运算符只能作为成员函数重载。
|
22天前
|
C++
c++学习笔记02 运算符
C++学习笔记,介绍了C++中的运算符,包括基本的加减乘除、求模、前后置递增递减、赋值运算符、比较运算符和逻辑运算符的使用及其注意事项。
29 6
|
24天前
|
编译器 C++ 索引
C++虚拟成员-虚函数
C++虚拟成员-虚函数
|
27天前
|
编译器 C++
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
|
27天前
|
编译器 C++
virtual类的使用方法问题之静态和非静态函数成员在C++对象模型中存放如何解决
virtual类的使用方法问题之静态和非静态函数成员在C++对象模型中存放如何解决
|
2月前
|
安全 编译器 C++
C++一分钟之-C++中的属性命名空间
【7月更文挑战第22天】C++11引入属性作为元数据,虽无内置属性命名空间,但可通过自定义属性与命名空间组合实现类似效果。例如,创建`perf`命名空间存放`slow`和`fast`属性来标记函数性能。正确使用属性需注意位置、避免重复和确保与实现一致,以提升代码可读性和编译器理解。通过模拟属性命名空间,可以更有效地管理和使用属性。
40 1
|
2月前
|
编译器 数据安全/隐私保护 C++
C++一分钟之-属性友元与访问控制
【7月更文挑战第9天】C++中的友元机制允许非成员函数或类访问私有和保护成员,打破了封装性。友元需在类内声明,常见的错误包括忘记声明、过度使用及误解友元的非继承性。要避免错误,应明确声明友元,限制其使用,并理解其局限。示例展示了如何声明和使用友元函数来访问私有数据。谨慎使用友元以保持代码的健壮性和可维护性。
19 1
|
2月前
|
存储 C++
【C++】string类的使用③(非成员函数重载Non-member function overloads)
这篇文章探讨了C++中`std::string`的`replace`和`swap`函数以及非成员函数重载。`replace`提供了多种方式替换字符串中的部分内容,包括使用字符串、子串、字符、字符数组和填充字符。`swap`函数用于交换两个`string`对象的内容,成员函数版本效率更高。非成员函数重载包括`operator+`实现字符串连接,关系运算符(如`==`, `&lt;`等)用于比较字符串,以及`swap`非成员函数。此外,还介绍了`getline`函数,用于按指定分隔符从输入流中读取字符串。文章强调了非成员函数在特定情况下的作用,并给出了多个示例代码。
|
2月前
|
C++
【C++】string类的使用④(常量成员Member constants)
C++ `std::string` 的 `find_first_of`, `find_last_of`, `find_first_not_of`, `find_last_not_of` 函数分别用于从不同方向查找目标字符或子串。它们都返回匹配位置,未找到则返回 `npos`。`substr` 用于提取子字符串,`compare` 则提供更灵活的字符串比较。`npos` 是一个表示最大值的常量,用于标记未找到匹配的情况。示例代码展示了这些函数的实际应用,如替换元音、分割路径、查找非字母字符等。