1. 程式人生 > >實現C++string的賦值函式

實現C++string的賦值函式

之前一直敲C語言,對C++有點疏忽了,前兩天看到《劍指offer》一道關於這個問題解法的面試題,於是動手敲了一下,卻發現自己給的解法只是初級解法。總結原因,還是自己沒有充分利用C++的特性,只是站在C語言的角度在寫C++程式。

首先,分析一下這個問題要求:

           1.實現物件賦值(深拷貝);

           2.傳入物件應該是const的,防止物件的值被修改;

           3.應該有返回值,也就是說,要能作為左值;

           4.要有異常處理機制(這裡使用if,沒有使用try catch);

           5.還有最後一點,容易被忽略若開始時指標有指向,應該先釋放這塊空間,否則則會造成記憶體洩露,還有個細節就是,delete釋放空間後,記得將指標的指向置為NULL(畢竟C++不好寫,哈哈^-^);

           說到這裡,我建議你可以試著實現一下以上的要求,可能你會和我一樣,會給出課本上的那種所謂的“標準解法”,等你實現之後,你再看看我給出的參考《劍指offer》給出的“高階解法”,你可能會和我一樣,感嘆它的精妙。下面給出程式碼實現:

#include <iostream>
#include <new>
#include <cstring>
#include <cstdlib>
using namespace std;

class my_string
{
private:
    char *str_ptr;
public:
    my_string();
    my_string(char *str_ptr);
    my_string(const my_string &str);
    my_string &operator = (const my_string &str);
	void print();
	~my_string();
};
void my_string::print()
{
    cout << str_ptr << endl;
}
my_string::my_string(char *str_ptr)
{
    if (str_ptr == NULL) {
	    cerr << "argument is error" << endl;
	}
    this->str_ptr = new(nothrow)char[strlen(str_ptr) + 1];
	if (this->str_ptr == NULL) {
		cerr << "merrory is full" << endl;
		exit(1);
	}
	strcpy(this->str_ptr, str_ptr);
}
my_string::my_string(const my_string &str) 
{
    if (str.str_ptr) {
        this->str_ptr = new(nothrow)char[strlen(str.str_ptr) + 1];
	    if (this->str_ptr == NULL) {
	        cerr << "merrory is full" << endl;
            exit(1);
	    }
		
	    strcpy(this->str_ptr, str.str_ptr);
   }
}
my_string::~my_string()
{
    delete []str_ptr;
	this->str_ptr = NULL;
}
/******************************************************
 *********************高階解法*************************
 *****************************************************/
//使用臨時變數的優勢:
//1.將new的判錯交給拷貝建構函式
//2.將this->str_ptr指向的原有單元的釋放交給temp的解構函式
//3.從而簡化了程式碼
my_string &my_string::operator = (const my_string &str)
{
    if (&str != this && str.str_ptr != NULL) {
	    my_string temp(str);
		char *temp_ptr = this->str_ptr;
		this->str_ptr  = temp.str_ptr;
		temp.str_ptr    = temp_ptr;
	}

	return *this;
}
my_string::my_string()
{
	str_ptr = NULL;
}
    
int main(int argc, char* argv[])
{
    char str[100] = {0};
	my_string *obj_ptr = NULL;	
	my_string obj1, obj2;

	cout << "Please input a string:" << endl;
    cin  >> str;
	obj_ptr = new(nothrow)my_string(str);
	
	if (obj_ptr == NULL) {
	    cerr << "memory is full" << endl;
	    exit(1);
	}

	obj1 = obj2 = *obj_ptr;
	obj1.print();
	obj2.print();
	obj_ptr->print();

	delete obj_ptr;
	obj_ptr = NULL;
}
注:賦值號過載的實現函式和《劍指offer》有些許細微差別,我覺得我這樣寫可能程式碼的健壯性更好一點。