重载操作符来处理我自己的类作为std类是一个好做法吗?
Is overloading operators to handle my own classes as std classes a good practice?
我一直在阅读Deitel的c++ Fundamentals, Deitel先生着重于重载标准操作符,以便为自定义类及其成员提供标准功能。我的意思是,例如,我可以直接说cout << object;
cout << object.memberFunction();
这种技术确实允许链接和更快的输入,但它需要操作符重载实现,即使我仍然是一个新手,我觉得代码实际上使可读性降低,特别是如果有许多类成员你必须记住哪些是操作符重载的等等。没有重载操作符的代码可读性更强,而且可以节省重载代码。
所以我的问题是我是否应该花时间学习操作符重载?我是c++的新手,欢迎有更多实践和经验的人给出答案。操作符重载的好处会超过实现它所付出的努力和降低的代码可读性吗?
您当然应该花时间学习操作符重载。然而,这并不意味着你应该或不应该使用操作符重载。但没有学习,你就无法真正做出决定。决定使用你不熟悉的东西即使不是不可能,也是很困难的。你总是会发现一些你不知道的东西更难用,即使它实际上更容易。
也就是说,根据具体情况做你认为最好的事情。如果在您的情况下,您发现操作符重载使代码可读性降低,那么无论如何都不要这样做。然而,在某些情况下它是有用的。但是,由于重载操作符通常是出于可读性的目的,如果您发现它不适用于您的情况,请远离它。
我很想说,没有什么可以学习的操作符重载;重载操作符只是有趣的命名函数。什么你必须知道什么时候超载是合适的,什么时候是合适的不是。某些习惯用法或多或少是标准的:数字类型重载适当的数字运算符(+
等),智能指针过载指针操作(*
和->
),支持索引的容器类型重载[]
和函数对象重载()
。这就是它适用于特殊情况。虽然这可以说是一种虐待,但如果你定义迭代器时,您将希望它支持标准迭代器成语(即++
、*
、->
和==
/!=
)。
除了这些,还有三个操作符将被重载对于许多不同类型的类:赋值是使用=
和使用<<
和>>
完成流的插入和提取。如果您希望您的类支持其中的任何一种,您应该使用过载。比较用==
和!=
表示相等,<
,<=
, >
和>=
为不等式。但不要因为不平等而超载除非它在语义上是重要的。最好提供一个用于std::map
和std::set
的显式排序函数误导读者,让他们认为你已经在语义上定义了重要的排序。您可能需要将std::less
专门用于您的类在这种情况下;<
将不起作用,或者将有不适当的语义作为键使用,但是std::less
将定义一个任意的排序这将。虽然不是操作符重载,但如果类型是作为关联容器中的键,您还需要提供函数hash_code
和struct std::hash
的实例化。
compare
(返回int
)大于,等于或大于0),表示不相等;我将定义一个public函数compare
,然后派生如下:
template<typename T>
struct ComparisonOperators
{
friend bool operator==( T const& lhs, T const& rhs )
{
return lhs.compare() < 0;
}
// ...
// The same for the other five operators.
};
(我的实现实际上有点复杂,因为它使用元编程为==
和!=
使用isEqual
,如果类提供它。)
我对二进制算术运算符使用了类似的技术,定义用+=
来表示+
,等等。我还将它用于IO,用术语定义<<
print
和>>
与parse
的比值;这主要用于操作符需要是多态的
操作符重载在很多情况下可以提高可读性,在这些情况下它是有用的。你可能第一次遇到了一个不幸的例子;特别是对于操作符<<,就会发生这种情况,您已经学到了操作符重载的第一个教训:有时,显式方法调用更清晰。但有时并非如此。例如,考虑c++中一个典型的矩阵乘法(例如使用特征矩阵):
a = b * c;
和Java中的
a = b.multiplyUsingTheMatrixMultiplicationAlgorithmThatsMathYay(c);
操作符重载使代码更具可读性。对于这些情况,您应该学习或至少了解操作符重载,并且只有在这些情况下才应该应用它。
实际上,我认为标准的重载操作符是理所当然的,并没有考虑到每种类型都有单独的实现。操作符重载在很多方面都很重要,比如在使用模板的时候,节省的时间比我最初意识到的要多得多。
通常使用友外部操作符,如下所示
friend std::ostringstream & operator<<(std::ostringstream &oss, Type &type);
和
std::ostringstream & operator<<(std::ostringstream &oss, Type &type)
{
oss << type.attr1;
oss << type.attr2;
oss << type.attr3;
return oss;
}
所以你可以这样调用:
Type val;
...
std::cout << val << std::end;
- 在多个核心中处理一个HTTP请求
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 模板函数如何处理可能共享一个交集的多个类型名称?
- 是否可以通过每次在内存中仅保存一个平铺来处理完整的平铺 tiff 图像?
- 如何处理没有默认构造函数但在另一个构造函数中构造的对象?
- C++在一个映射中存储不同的指针类型(并处理销毁)
- 多 GPU 批处理 1D FFT:似乎只有一个 GPU 可以工作
- 处理程序的模块列表中有一个错误的模块"WebSocketModule"
- 有没有办法在使用 GLFW 按下按键后只处理一个输入事件?
- 专门处理一个参数(C++模板)的两个模板参数
- 在C++中做一个场景问题,我不确定如何处理布尔和if循环
- 我对C++程序有一个未定义的参考,不知道如何处理它
- 创建一个函数,如果元素在unordered_set中,则返回 true,如何处理模板
- GTK 将一个处理程序用于多个小部件
- 如何保存指针地址,以便另一个指针可以继续处理它
- Howo 使用 cl 预处理为 masm 组装生成一个单独的文件
- 我有一个预处理的 C/C++ 源文件 (cacti.i).如何从这个 .i 文件生成可执行二进制文件,以便我可以像 ./
- QlineEdit:显示一个处理过的文本,而不是输入的文本,而是保留它(自定义回声模式)
- 处理另一个类中类动态分配的对象数组
- 在调用前一个处理程序的完成处理程序之前异步发送数据是否有效