归咎于寂寞的夏天.|

Phantasia1116

园龄:1年7个月粉丝:0关注:7

2024-03-06 21:28阅读: 18评论: 0推荐: 0

重载操作符

  • 首先 c++ 重载操作符只能在 class 或者结构体中
  • 以下面的代码为例
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e5 + 9;
struct Book
{
int a, b, c;
bool operator<(const Book &x) const
{
if (a != x.a)
return a < x.a;
if (b != x.b)
return b < x.b;
return c < x.c;
}
} p[N];
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n;
cin >> n;
for (int i = 1; i <= n; ++i)
cin >> p[i].a >> p[i].b >> p[i].c;
sort(p + 1, p + n + 1);
for (int i = 1; i <= n; ++i)
cout << p[i].a << " " << p[i].b << " " << p[i].c << "\n";
return 0;
}

在这段代码中,定义了一个 Book 结构体,其中包含三个整数类型的成员变量 abc。重点在于对 < 运算符的重载,这是在 C++中自定义类型排序逻辑的一种常见做法。通过重载 < 运算符,我们可以使 Book 类型的对象能够使用标准库函数 std::sort 进行排序。

< 运算符的重载

bool operator<(const Book &x) const
{
if (a != x.a)
return a < x.a;
if (b != x.b)
return b < x.b;
return c < x.c;
}

对代码的解释

这段代码重载了 < 运算符,使得两个 Book 对象可以直接比较。这里的比较逻辑是:

  1. 首先比较 a 字段:如果当前对象的 a 字段不等于另一个对象的 a 字段,则比较这两个 a 字段的大小。如果当前对象的 a 小于另一个对象的 a,则返回 true,表示当前对象应排在另一个对象之前;否则,返回 false

  2. 然后比较 b 字段:如果 a 字段相等,接下来比较 b 字段。逻辑与比较 a 字段相同。

  3. 最后比较 c 字段:如果 ab 字段都相等,最后比较 c 字段,逻辑也相同。

主函数 main

main 函数中,首先通过 ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); 禁用 C 和 C++标准库之间的同步,从而加速输入输出操作。

接着,读入整数 n,表示 Book 对象的数量。通过一个循环,读取每个 Book 对象的 abc 字段值。

使用 std::sort 函数,按照重载的 < 运算符定义的逻辑,对数组 p 中从索引 1n(包含)的 Book 对象进行排序。

最后,通过另一个循环,按排序后的顺序输出每个 Book 对象的 abc 字段。

总结

通过重载 < 运算符,该代码实现了 Book 结构体对象的自定义排序逻辑。这种方法使得 Book 对象可以直接使用 std::sort 等标准库算法进行排序,提供了一种灵活且强大的方式来定义对象间的排序规则。

这一行代码 bool operator<(const Book &x) const 是在 C++中对 < 操作符进行重载的声明,具体到 Book 结构体的上下文中。这个操作符重载使得可以直接比较两个 Book 类型的对象。下面详细解释这段代码的各个部分:

详细解释 bool operator<(const Book &x) const,以及为什么能在结构体内对操作符进行重载,vector 是否可以完成

解释

  • bool:这是函数的返回类型,表示该操作符重载函数返回一个布尔值,用于指示调用对象是否小于传入的参数对象。

  • operator<:这指明正在被重载的是 < 操作符。

  • (const Book &x):这是函数的参数列表,表示该函数接受一个类型为 const Book& 的参数。const 保证传入的对象 x 不会在函数中被修改,& 表示传递的是对象的引用,避免了对象的拷贝,提高了效率。

  • const(在参数列表后):这个 const 表示该成员函数不会修改调用它的对象的状态。这是常量成员函数的标记,确保了在该函数内部不能修改任何成员变量(除了那些被声明为 mutable 的成员变量)。

为什么能在结构体内对操作符进行重载?

在 C++中,结构体(struct)与类(class)非常相似,唯一的区别是默认的访问权限:struct 的成员默认是公开的(public),而 class 的成员默认是私有的(private)。因此,你可以在结构体内部定义成员函数,包括操作符重载函数,就像在类中一样。这提供了一种定义如何通过标准操作符对自定义类型进行操作的方式,使得自定义类型的使用更加直观和自然。

vector 可以完成操作符重载吗?

std::vector 是 C++标准模板库(STL)的一部分,它是一个模板类,不是用户定义的类型,因此你不能为 std::vector 直接添加操作符重载。操作符重载需要在类或结构体的定义内部进行。然而,你可以对存储在 vector 中的自定义类型(如 Book)进行操作符重载,就像上面的例子那样。然后,你可以利用这些重载来对 vector<Book> 进行排序等操作,因为 std::sort 等函数会使用这些重载来比较 vector 中的元素。

总之,操作符重载在结构体或类内部定义,使得这些自定义类型可以以一种直观和自然的方式使用操作符。虽然不能直接为 std::vector 这样的模板类重载操作符,但可以通过重载存储在其中的自定义类型的操作符来实现间接的效果。

参数是如何被调用

在 C++中,当对操作符进行重载并使用这个重载操作符比较两个对象时,参数的调用遵循特定的规则。以 bool operator<(const Book &x) const 为例,这里解释如何调用这个重载的 < 操作符以及参数是如何被传递的。

操作符重载函数的调用

假设有两个 Book 类型的对象:book1book2。当你使用 book1 < book2 这样的表达式时,这实际上是在调用 book1operator< 函数,并将 book2 作为参数传递给这个函数。

Book book1, book2;
// 假设book1和book2已经被适当初始化
if (book1 < book2) {
// 逻辑处理
}

这个表达式等价于直接调用:

if (book1.operator<(book2)) {
// 逻辑处理
}

参数的传递

  • 对象 book1:作为比较操作的调用方,book1 的状态不会被修改,因为 operator< 被声明为 const。这意味着在该函数内部不能修改 book1 的任何成员变量。

  • 对象 book2:作为参数传递给 operator< 函数。通过使用 const Book &x 作为参数类型,book2 是以引用的方式传递的,同时保证了在 operator< 函数内部不会修改 book2。使用引用传递避免了不必要的对象拷贝,提高了效率。同时,const 修饰符确保了函数内部不能修改传入对象的状态,这是一种良好的实践,可以保护函数外部的数据不被意外修改。

总结

在 C++中,当你对重载的操作符进行调用时,调用对象作为操作符函数的隐式调用方(相当于函数的 this 指针指向的对象),而其他参数则根据操作符函数的声明被显式传递。通过这种方式,C++允许开发者定义类型如何响应标准操作符,既保持了代码的直观性,又提供了强大的自定义能力。

在提供的代码片段中,< 操作符被重载用于 Book 结构体,使得 Book 对象可以被直接比较。这个重载的操作符实际上被使用在 main 函数中的 sort 函数调用里:

sort(p + 1, p + n + 1);

这行代码使用 std::sort 来对 Book 类型的数组 p 进行排序,范围从 p[1]p[n](注意 C++中数组默认是从0开始索引的,但这里从1开始使用,可能是基于特定的需求或习惯)。std::sort 函数内部会多次比较数组中的元素来确定它们的排序顺序。当 std::sort 需要比较两个 Book 对象时(例如,决定哪个对象应该排在前面),它就会调用我们重载的 < 操作符。

这种比较逻辑允许 std::sort 根据 Book 对象的 abc 成员变量的值来排序这些对象。具体的比较逻辑首先比较 a 值,如果 a 值相同,则比较 b 值,如果 b 值也相同,则最后比较 c 值。这样,std::sort 可以根据重载的 < 操作符正确地排序 Book 数组。

总结

< 操作符的重载在 Book 对象数组的排序中发挥了作用,即在 std::sort 函数内部被隐式调用以确定数组中元素的顺序。这展示了操作符重载在自定义类型排序中的强大能力,使得自定义类型可以像内置类型那样,通过标准库算法进行有效的排序和比较。

本文作者:Phantasia1116

本文链接:https://www.cnblogs.com/Phantasia/p/18057650

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Phantasia1116  阅读(18)  评论(0编辑  收藏  举报
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示