运算符重载

我们知道如何在遵循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++.

你可能感兴趣的:(运算符)