Operator overloading and copy depth

For some arithmetic symbol (+, -, *, / ....), we are not satisfied with its original mode of operation, but to be in the unique objects were using (such as addition and subtraction of a negative number), but the compiler It will be allowed to do so, because the operator will be the original type mismatch operation failed. So we need to be overloaded operator that give it new meaning, to meet our needs.

As complex_a and complex_b two complex objects are two complex and demand, hoping to write directly to: complexa + comple_b

object of operator overloading are: operator extend the application provided in C ++, so that it can act on the object .

 same operator, the different behavior of different types of operands, occurred.
For  plural referents: complex_a + complex_b => generates a new plural referents
 For integer: 5 + 4 = 9

Operator overloading essence function overloading , which may function as an ordinary overload, a member may be overloaded , while the expression containing the conversion algorithms, call the corresponding operator function to complete the operation overloaded. ( Match depending on the type of parameter )

 1 class Complex 
 2 {
 3     public:double real,imag; 
 4     Complex( double r = 0.0, double i= 0.0 ):real(r),imag(i) {}
 5     Complex operator-(const Complex & c); 
 6 };
 7 Complex operator + ( const Complex & a, const Complex & b)
 8 {   
 9     return Complex( a.real+b.real,a.imag+b.imag); //Returns a temporary object 
10  }
 . 11 Complex Complex :: operator - ( const Complex & C)
 12 is  {
 13 is      return Complex (Real - c.real, imag - c.imag); // returns a temporary object 
14  }
 15  // weight when the carrier is a member function, the number of parameters to decrease a number of operators.
16  // heavy load function is normal, the number of parameters as the number of operators. 
. 17  int main ()
 18 is  {
 . 19      Complex A ( . 4 , . 4 ), B ( . 1 , . 1 ), C;
 20 is      C = A + B; // equivalent to operator + = C (A, B) 
21 is     cout << c.real << "," << c.imag << endl;//5,5,
22     cout << (a-b).real << "," << (a-b).imag << endl;//3,3
23     //a-b等价于a.operator-(b)
24     return 0;
25 }
  • Assignment Operator Overloading

Sometimes both sides of the desired type of assignment operator may not match the operator, for example, to a variable of type int assign a Complex object, the assignment of a char * string to a string type of object, then you need to override the assignment operator symbol "=." Assignment operator '=' can only be overloaded as a member function

 1 class String 
 2 {
 3     private:    
 4         char * str;
 5     public:
 6         String ():str(new char[1]) { str[0] = 0;}
 7         const char * c_str() { return str; };
 8         String & operator = (const char * s);
 9     String::~String( ) { delete [] str; }
10 };
11 String & String::operator = (const char * s) 
12 { //重载“=”以使得 obj = “hello”能够成立
13     delete [] str;
14     str = new char[strlen(s)+1];
15     strcpy( str, s);
16     return * this;
17 }
18 int main()
19 {
20     String s;
21     s = "Good Luck," ; //等价于 s.operator=("Good Luck,");
22     cout << s.c_str() << endl;
23     // String s2 = "hello!"; //error
24     s = "Shenzhou 8!"; //等价于 s.operator=("Shenzhou 8!");
25     cout << s.c_str() << endl;
26 return 0;
27 }
28 // 输出:
29 // Good Luck,
30 // Shenzhou 8!
  • 浅拷贝和深拷贝

一个字符串的例子

1 String S1, S2;
2 S1 = “this”;
3 S2 = “that”;
4 S1 = S2;

这几句的含义很清楚,一个S1串和S2串,并将S2赋值给S1,此时S1就和S2是一样的值。。但是....这样却不是我们理解的那种copy

它是在将s2赋值给s1的时候,将原来指向s1的指针取指向s2

原本指向'this'字符串的指针s1指向了'that'的字符空间,这样原来的'this'的字符空间就找不到了(变成内存垃圾)。

这就是浅拷贝此时若我们释放s1所指向的存储空间,将会释放掉'that',但是继续释放s2时,会发生问题(程序崩溃),因为此刻s2指向的存储空间已经被s1所释放了

但是原来的'this'却孤独的无人问津,好惨 ...所以这样是很不妥的。。。或者,我们更换此刻s1的值,又导致'that'被更换了。。。就会一团糟。。

所以需要对原来的'='号进行重载(深拷贝:生成一个新的,值与当前的值一样的,不同地址空间的复制,互相的操作不相往来的那种,即真正意义上的copy)

 1 class String 
 2 {
 3 private: 
 4     char * str;
 5 public:
 6     String ():str(new char[1]) 
 7     { 
 8         str[0] = 0;
 9     }
10     const char * c_str() 
11     { 
12         return str; 
13     };
14     String & operator = (const char * s)
15     {
16         delete [] str;//删除原来的str
17         str = new char[strlen(s)+1];//开辟足够大的存储空间
18         strcpy( str, s);//将s拷贝过来
19         return * this;//这样s1就会指向新分配的存储空间
20     };
21     ~String( ) 
22     { 
23         delete [] str; 
24     }
25 };

但是,这样写还是有一点小问题的。如果我写了这个 s=s,就问又有小问题。这样在赋值时,左边的s先被delete,然后将右边s赋值给左边的s,但是右边的s已经没了啊?!?!?这样就出错了。所以代码要继续修改,成这样

1 String & operator = (const String & s)
2 {
3     if( this == & s) //
4         return * this;//防止出现自己给自己赋值出错的情况,直接返回就行了
5     delete [] str;
6     str = new char[strlen(s.str)+1];
7     strcpy( str,s.str);
8     return * this;
9 }

注意,返回值类型是String & 型这样是为了对应原来 “=”运算符的左右两边类型

1 //
2 a = b = c;
3 (a=b)=c; //会修改a的值
4 //分别等价于:
5 a.operator=  (b.operator=(c));
6 (a.operator=(b)).operator=(c);

现在应该可以了。

但是。。。。

1 //为 String类编写复制构造函数的时候,会面临和不重载的 = 同样的问题,即默认构造函数会将=变成复制的操作,是浅拷贝!!所以我们用同样的方法处理。写个复制构造
2 String( String & s) 
3 {
4     str = new char[strlen(s.str)+1];
5     strcpy(str,s.str)
6 }

 

Guess you like

Origin www.cnblogs.com/ygsworld/p/11324550.html