运算符重载

我们知道如何在遵循C++语法条件下实现"虚函数、重载运算符函数"。

我认为当我们尝试来实现重载运算符的虚函数时需要知道:函数签名、redefine、overload、override、虚表、RTTI、编译器默认的插入行为。(此处没有使用虚基类,因此不需要虚表表的知识)

和 同学 以及 ”EA娘家人“分别讨论了这个问题,均没有得出详细的解答,不知到android源码中有没有,没仔细找。

参考:

http://stackoverflow.com/questions/669818/virtual-assignment-operator-c

http://www.icu-project.org/docs/papers/cpp_report/the_assignment_operator_revisited.html

http://www.cplusplus.com/forum/beginner/18705/

《C++ Primer》4ed_CN    p_646~652

要求:

1、派生类继承自基类,派生类与派生类相加时可以完成派生类实例中相应成员(包括继承自基类中的成员)的相加。(这个简单)

2、基类的指针指向一个派生类的实例,通过调用重载“+”运算符函数,使得通过基类的指针可以完成与另一个派生类实例的加法。

关于第1点我们很容实现,只要在派生类的operator+中主动调用基类的operator+就可以了;

关于第2点,我想如果可以通过基类的指针直接调用派生类的operator+就可以了,但是如果要这样做就需要:(1)operator+为虚函数;(2)派生类的operatpr+的形参类型与基类的operator+的形参类型完全相同;这里面的第二个要求固然可以实现,但是个人感觉不好,代码的可读性也较差。

关于第2点,我的想法是:operator+不声明为虚函数,相应的类类型的指针都在编译时即确定调用各自类类型的operator+函数。在各自的operator+中调用一个虚函数来完成加法函数,每次调用该虚函数就会调用最终派生类的相应虚函数(通过虚表实现),再在派生类的虚函数中依次显式的调用上一级的相应的虚函数。

如下是我的解法,开销是大了点……

  1 #include <iostream>                                                                                                
  2 #include <typeinfo>
  3 using namespace std;
  4 
  5 class BASE
  6 {
  7     private:
  8         int i;  
  9     protected:
 10         virtual const BASE& ADD(const BASE& thiz)
 11         {       
 12             cout << "BASE ADD" << endl;
 13             i += thiz.i; 
 14             return *this;
 15         }       
 16 
 17         virtual const BASE& ASSIGN(const BASE& thiz)
 18         {       
 19             cout << "BASE ASSING" << endl;
 20             i = thiz.i; 
 21             return *this;
 22         }       
 23 
 24     public: 
 25         BASE(void):i(1)
 26         {       
 27             cout << "BASE constructor" << endl;
 28         }       
 29 
 30         virtual ~BASE(void)
 31         {       
 32             cout << "BASE deconstructor" << endl;
 33         }       
 34 
 35         const BASE& operator + (const BASE& thiz)
 36         {       
 37             cout << "BASE operator +" << endl;
 38             if (typeid(*this) != typeid(thiz))
 39                 return *this;
 40 
 41             ADD(thiz);
 42 
 43             return *this;
 44         }
 45 
 46         const BASE& operator = (const BASE& thiz)
 47         {
 48             cout << "BASE operator =" << endl;
 49             if (typeid(*this) != typeid(thiz))
 50                 return *this;
 51 
 52             ASSIGN(thiz);
 53 
 54             return *this;
 55         }
 56 };
 57 
 58 class DERIVE: public BASE
 59 {
 60     private:
 61         int j;
 62     protected:
 63         const DERIVE& ADD(const BASE& thiz)
 64         {
 65             BASE::ADD(thiz);
 66             cout << "DERIVE ADD" << endl;
 67             const DERIVE &org = dynamic_cast<const DERIVE&>(thiz);
 68             j += org.j;
 69             return *this;
 70         }
 71 
 72         const DERIVE& ASSIGN(const BASE& thiz)
 73         {
 74             BASE::ASSIGN(thiz);
 75             cout << "DERIVE ASSING" << endl;
 76 
 77             const DERIVE &org = dynamic_cast<const DERIVE&>(thiz);
 78             j = org.j;                                                                                             
 79             return *this;
 80         }
 81 
 82     public:
 83         DERIVE(void):j(2)
 84         {
 85             cout << "DERIVE constructor" << endl;
 86         }
 87 
 88         ~DERIVE(void)
 89         {
 90             cout << "DERIVE deconstructor" << endl;
 91         }
 92 
 93         const DERIVE& operator + (const DERIVE& thiz)
 94         {
 95             cout << "DERIVE operator +" << endl;
 96             if (typeid(*this) != typeid(thiz))
 97                 return *this;
 98 
 99             ADD(thiz);
100 
101             return *this;
102         }
103 
104         const DERIVE& operator = (const DERIVE& thiz)
105         {
106             cout << "DERIVE operator =" << endl;
107             if (typeid(*this) != typeid(thiz))
108                 return *this;
109 
110             ASSIGN(thiz);
111 
112             return *this;
113         }
114 };
115 
116 int main(void)
117 {
118     DERIVE one;
119     cout << "1" << endl;
120     DERIVE two;
121     cout << "2" << endl;
122 
123     one = one + two;
124     cout << "3" << endl;
125 
126     BASE *p = &one;
127     p->operator+(two);
128     cout << "4" << endl;
129 
130     return 0;
131 }

运行结果

 1 BASE constructor
 2 DERIVE constructor
 3 1
 4 BASE constructor
 5 DERIVE constructor
 6 2
 7 DERIVE operator +
 8 BASE ADD
 9 DERIVE ADD
10 DERIVE operator =
11 BASE ASSING
12 DERIVE ASSING
13 3
14 BASE operator +
15 BASE ADD
16 DERIVE ADD
17 4
18 DERIVE deconstructor
19 BASE deconstructor
20 DERIVE deconstructor
21 BASE deconstructor

 记录下一段话,我们应该慎重地完成重载的等号运算符虚函数:

  A virtual assignment operator is allowed, but is complex to create correctly. The danger is that you might assign a base class to a derived class, causing inconsistent vaues in the derived class's data members. Attempting virtual assignment is best left until you are more experienced in C++.

原文地址:https://www.cnblogs.com/openix/p/3259746.html