1. 程式人生 > >琴入目,往事沉浮,風已起,琴塵飛揚,迷離了前方。

琴入目,往事沉浮,風已起,琴塵飛揚,迷離了前方。

在程式筆試面試過程中String類的是實現是經常被問到的,為了便於記憶,現在整理一下。

  1 #ifndef STRING_H_
  2 #define STRING_H_
  3 #include <stdio.h>
  4 #include <iostream>
  5 using namespace std;
  6 class String
  7 {
  8     friend ostream &operator<<(ostream &,const String &);
  9     friend istream &operator>>(istream &,String &);
 10     public:
 11     String(const char* str=NULL);
 12     String(const String &other);
 13     ~String(void);
 14     const String &operator = (const String &other);
 15     private:
 16     char *m_data;
 17 };
 18 #endif
 19 

 1 #include "String.h"
  2 #include <string.h>
  3 #include <stdio.h>
  4 using namespace std;
  5 String::String(const char *str)
  6 {
  7     cout<<"constructor function is called.\n";
  8     if(NULL==str)
  9     {
 10         m_data=new char[1];
 11         *m_data='/0';
 12     }
 13     else
 14     {
 15         int length=strlen(str);
 16         m_data=new char[length+1];
 17         strcpy(m_data,str);
 18     }
 19 }
 20 String::~String(void)
 21 {
 22     cout<<"destructor function is called.\n";
 23     delete [] m_data;
 24 }
 25 String::String(const String &other)
 26 {
 27     cout<<"copy constructor function is called.\n";
 28     int length=strlen(other.m_data);
 29     m_data=new char[length+1];
 30     strcpy(m_data,other.m_data);
 31 }
 32 const String& String::operator=(const String& other)
 33 {
34     cout<<"assign function is called.\n";
 35     if(this==&other)
 36         return *this;
 37     delete[] m_data;
 38     int length=strlen(other.m_data);
 39     m_data=new char[length+1];
 40     strcpy(m_data,other.m_data);
 41     return *this;
 42 }
 43 ostream &operator<<(ostream &output,const String &s)
 44 {
 45     output<<s.m_data;
 46     return output;
 47 }
 48 istream &operator>>(istream &input,String &s)
 49 {
 50     char temp[100];
 51     input>>temp;
 52     s=temp;
 53     return input;
 54 }

  1 #include <String.h>
  2 #include <iostream>
  3 using namespace std;
  4 int main()
  5 {
  6     String s="hello";
  7     cout<<s<<endl;
  8     String i;
  9     cin>>i;
 10     cout<<i<<endl;
 11     return 0;
 12 }
 13 

輸入和輸出操作符不能宣告為類的成員函式,必須為普通函式,並且為類的友元函式,因為他們都要訪問類的成員函式,輸入輸出操作符的左運算元是IO流物件的引用,右運算元才是類的物件,因此不能為類的成員函式(類的成員函式隱含的第一個運算元,是指向該類或該類派生類物件的this指標)。

     在這裡過載了有一個引數的建構函式,此時系統將不會提供不帶引數的建構函式。

     在建構函式中使用了深拷貝,在某些狀況下,類內成員變數需要動態開闢堆記憶體,如果實行位拷貝,也就是把物件裡的值完全複製給另一個物件,如A=B。這時,如果B中有一個成員變數指標已經申請了記憶體,那A中的那個成員變數也指向同一塊記憶體。這就出現了問題:當B把記憶體釋放了(如:析構),這時A內的指標就是野指標了,出現執行錯誤。

    深拷貝和淺拷貝可以簡單理解為:如果一個類擁有資源,當這個類的物件發生複製過程的時候,資源重新分配,這個過程就是深拷貝,反之,沒有重新分配資源,就是淺拷貝。