C++多态与虚拟:运算符重载(Operator Overloading)

operator,overloading · 浏览次数 : 5

小编点评

**Operator Overloading** **什么是运算符重载?** 运算符重载是指一个编程语言允许定义多个与特定运算符相关的函数,并根据传入的参数类型自动选择正确的函数实现。 **在 C++ 中的运算符重载** 在 C++ 中,运算符重载可以通过以下方式实现: * 通过函数名选择函数。 * 通过类型隐式转换实现类型转换。 * 通过模板定义定义泛型函数。 **示例** ```cpp #include using namespace std; // 定义一个与 int 类型相关的运算符重载 double operator+(int a, int b) { return a + b; } int main() { int a = 10, b = 20; // 使用运算符重载加操作 double result = a + b; // 打印结果 cout << result << endl; return 0; } ``` 该代码定义了一个与 `int` 类型相关的运算符重载,名为 `+` 的运算符可以用于加两个 `int` 类型的值。当调用 `a + b` 时,实际上调用了 `operator+(int, int)` 函数。 **其他操作符重载** 除了 `+` 之外,还有以下几种操作符重载: * `-` 运算符:`a - b` * `*` 运算符:`a * b` * `/` 运算符:`a / b` * `%` 运算符:`a % b` * `==` 运算符:`a == b` * `!=` 运算符:`a != b` **使用运算符重载** 使用运算符重载可以简化代码并提高可读性。例如,以下代码使用运算符重载来计算两个数字的平均值: ```cpp double average(int a, int b) { return (double)(a + b) / 2; } ``` **总结** 运算符重载是 C++ 中一种强大的功能,可以帮助我们简化代码并提高代码的可读性。通过定义不同的运算符重载,我们可以根据不同情况下选择正确的函数实现。

正文

  运算符重载:与function overloading异曲同工的是,C++提供所谓的Operator overloading。所谓operators是像  +(加)-(減)*(乘)/(除)>>(位右移)
<<(位左移)之类的符号,代表一种动作。

  面对operators,我们应该把他想像是一种函数,只不过形式比较特殊罢了。一般函数的参数出现在括号()之中,而operator的参数围绕着一个operator符号(之前或之后),编程语言内置的数据类型(比如整数`int`、浮点数`float`、长整数`long`等)所使用的操作符(比如加法`+`、减法`-`、乘法`*`等)是由语言本身直接提供的,而不是通过任何外部库或模块来实现的。

  C++允许程序员为class type's object设计专门的operators,使objects的操作能够像内建型别的一样的自然而直观。让operator以种形式呈现,但符号不变,这个就是operator overloading。

  Operator overloading的存在一下褒贬不一,支持者认为它使得程序代码变得更精简漂亮,反对者认为容易把程序员搞迷糊掉。但是,我想,谁都不可否认下面这样的程序代码确实是精简漂亮:
  

CString str1("Hello, I am J.J.Hou, ");
CString str2("How are you?");
CString str3 = str1 + str2; // + 是 CString的一个overloaded operator
// 于是 str3 为 "Hello, I am J.J.Hou, How are you?"
int i = 5;
double pi = 3.141592653;
cout << "i=" << i << " and pi=" << pi << endl;
// 于是 console 屏幕上出现"i=5 and pi=3.141592653"。

  现在让我示范一个overloaded operator的作法,只要在以下类的代码中加入第18~21行的+号的重载代码,即可完成CPoint的加法运算:

 1 class CPoint{
 2 
 3 public:
 4 
 5    CPoint()
 6    {
 7         _x=0;
 8 
 9    }
10 
11     CPoint(float y){
12 
13         _x=y;
14     }
15     float x(){return _x;}
16     void  x(float xval){_x=xval;}
17 
18     CPoint operator+(const CPoint& pt) const  //对+号进行重载
19     {
20         return CPoint(_x+pt._x);
21     }
22 
23 protected:
24     float _x;
25 
26 };

  以operator开头的函数,表示是个运算子。加法运算子需要左右两个运算元(operands),左侧运算元即成为本函数的this指向的对象,右侧运算元则是本函数的参数pt。上述函数代码如果像下面这样表示,会比较清晰,但两者其实是相同的(因为this指针是个隐藏参数):

    CPoint operator+(const CPoint& pt) const  //对+号进行重载
    {
        return CPoint(this->_x+pt._x);
    }

  有了上述的 CPoint::operator+,现在你可以这么使用它:

1 CPoint pt1(7.2), pt2(5.3), pt3;
2 pt3 = pt1 + pt2;
3 cout << "pt3.x = " << pt3.x() << endl; // 12.5

  C++中,<<和>>是最常用的重载运算符,用于表示对标准输入输出设备(如屏幕和键盘)的读写操作,极大地方便了编程,可替代繁琐的printf()和scanf()函数。这两个运算符在iostream库中定义,为C++编程提供了极大的便利。

  Insertion Operator << for stdout: <<本来是位左移运算符,但是在C++的标准库iostream中被改头换面,其左侧的运算元(operand)被指定为cout(console output device),右侧运算元是一个内建型别的objects。我们可以利用它很方便的对cout连续输出各种内建型别的数据或信息(也是一种objects),不必像C程序那样需要识别不同类型的数据在printf()中的格式符号(如 %s%d%f...):

1 #include <iostream.h>
2 ...
3 int i = 5;
4 double pi = 3.141592653;
5 cout << "i=" << i << " and pi=" << f << endl;

  Extraction Operator(>>) for stdin:>>本来是位右移运算符,但在C++标准的iostream中被改头换面,其左侧运算元是cin(console input device),右侧运算元是一个内建型别的object。例如:

1 #include <iostream.h>
2 ...
3 float f;
4 cout << "f = ? ";
5 cin >> f;

  程序使用者在健盘上输入,会经由cin装置流往f变量,其作用相当于C runtime library中的scanf()。

 

  Insertion Operator << for file:就像iostream支持对user‘s terminal的输入输出一样,c++另有一组class types支持对文件的输入输出:

  1.ifstream衍生自istream,支持文件的输入。

  2.ofstream衍生自 ostream,支持文件的输出。

  3. fstream衍生自 iostream 支持文件的输入输出

  如果需要这些class type,必须导入对应的header file。请注意,fstream已经含有iostream,所以不需要重复导入;

  下面是信息输入到文件的案例:

#0001 #include <fstream.h> // include iostream.h
#0002
#0003 int main()
#0004 {
#0005   cout << "All your keyboard input in monitor "
#0006       << "will into copy.txt.\n"
#0007       << "Terminate by ^Z\n\n";
#0008
#0009   ofstream outFile("copy.txt");
#0010   if (!outFile) {
#0011     cout << "Cannnot open copy.txt for output" << endl;
#0012     return -1;
#0013   }
#0014
#0015   char c;
#0016   while (cin.get(c)) // get each char from keyboard
#0017   outFile << c; // outFile.put(c) 亦 可
#0018
#0019   return 0;
#0020 }

  当程序执行后,会先提示输入,然后接收所有来自于键盘的字符,一一放进”copy.txt"文件中,直到接收到^z 才停止。

  Extraction Operator >> for file:下面是将文件的内案输出到屏幕上的示例:

#0001 #include <fstream.h> // include iostream.h
#0002
#0003 int main()
#0004 {
#0005   cout << "All text in copy.txt "
#0006   << "will stream into monitor.\n\n";
#0007
#0008   ifstream inFile("copy.txt");
#0009   if (!inFile) {
#0010     cout << "Cannnot open copy.txt for input" << endl;
#0011     return -1;
#0012   }
#0013
#0014   char c;
#0015   while (inFile.get(c)) // get each char from file
#0016   cout.put(c); // output to monitor
#0017
#0018   return 0;
#0019 }

  当程序执行后,会先给一个提示,然后从文件 "copy.txt" 中一一读出每一个字符,显示于屏幕上。上述第0015行如果改为while (inFile >> c) // get each char from file,虽然也能读出字符,但空格会被忽略,这个并非我们所想要的。

与C++多态与虚拟:运算符重载(Operator Overloading)相似的内容:

C++多态与虚拟:运算符重载(Operator Overloading)

运算符重载:与function overloading异曲同工的是,C++提供所谓的Operator overloading。所谓operators是像 +(加)-(減)*(乘)/(除)>>(位右移)<<(位左移)之类的符号,代表一种动作。 面对operators,我们应该把他想像是一种函数,只不过

C++多态与虚拟:Objects 实例化(Objects Instantiation)探究

一、Objects的创建 依据已有的class CPoint ,我们可以产生一个或多个object(对象),或者说是产生一个instance(实体): CPoint aPoint(7.2); // aPoint._x 初始值为 7.2 aPoint.x(5.3); // aPoint._x 现值为

C++多态与虚拟:C++编译器对函数名的改编(Name Mangling)

如果函数名称都相同(也就是被overloaded),编译器在面对你的函数唤起动作时,究竟是如何确定调用哪个函数实体呢?事实上,编译器把所有同名的overloaded functions视为不同的函数,并且以特殊方式对它们的函数名称做了手脚,以四个Add()函数为例: 1 int Add(int a,

C++ 多态与虚拟:Class 语法语义

1.object与class:在object-oriented programming编程领域,对象(object)有更严格的定义。对象是由数据结构和用于处理该结构的过程(称为methods)组成的实体(instance)。这些方法由对象接收的消息激活。一个对象的内部数据结构与其他对象完全隔离(此属

深入理解 C++ 中的多态与文件操作

C++ 多态 多态(Polymorphism)是面向对象编程(OOP)的核心概念之一,它允许对象在相同操作下表现出不同的行为。在 C++ 中,多态通常通过继承和虚函数来实现。 理解多态 想象一个场景,你有一个动物园,里面有各种动物,如猫、狗、鸟等。每个动物都有自己的叫声。使用面向对象编程,我们可以创

深入剖析C++多态的实现与原理-详解

目录多态基础虚函数虚函数的继承虚类/虚基类重写/覆盖条件:概念:多态的条件其他的多态行为多态中子类可以不写virtual协变代码举例继承遗留问题解决析构函数具体解决方式:题目1答案:解析:题目2答案:C++11 override和finalfinal功能1:禁用继承使用场景:功能2:禁用重写使用场景

C++ Virtual Functions

Virtual这个关键字在多态中扮演一个绝对重要的角色,只要member functions声明的前面加上virtual的关键字,他就会成为 Virtual member functions。任何一个class如果拥有virtual functions,就可以得到C++编译器的虚拟机制(virtua

深度解读《深度探索C++对象模型》之C++虚函数实现分析(三)

本系列深入分析编译器对于C++虚函数的底层实现,最后分析C++在多态的情况下的性能是否有受影响,多态究竟有多大的性能损失。

深度解读《深度探索C++对象模型》之C++虚函数实现分析(二)

本系列深入分析编译器对于C++虚函数的底层实现,最后分析C++在多态的情况下的性能是否有受影响,多态究竟有多大的性能损失。

深度解读《深度探索C++对象模型》之C++虚函数实现分析(一)

本系列深入分析编译器对于C++虚函数的底层实现,最后分析C++在多态的情况下的性能是否有受影响,多态究竟有多大的性能损失。