[面接問題]付与演算子関数

12396 ワード

タイトル:タイプCMyStringの宣言は次のとおりです.このタイプに付与演算子関数を追加してください.
class CMyString

{

    public:

    CMyString(char* pData=NULL);

    CMyString(const CMyString& str);

    ~CMyString(void);

    private:

    char* m_pData;

}

 
実装コードの注意点:
     1.戻り値のタイプをそのタイプの参照として宣言し、関数が終了する前に自分の参照(すなわち*this)を返すかどうかは、1つの参照を返すだけで、連続的に値を割り当てることができます.例えばstr 1=str 2=str 3;
     2.入力されたパラメータのタイプを定数参照として宣言するかどうか、定数参照でない場合、パラメータから実パラメータに至るまで、時間とメモリのオーバーヘッドを回避するレプリケーションコンストラクション関数が呼び出されます.また,受信インスタンスの状態を変えることを避けるためにconst修飾を加えるべきである.
     3.インスタンス自体のメモリを解放するかどうか.新しいメモリを割り当てた解放自体の既存のスペースを忘れた場合、プログラムにメモリが漏洩します.
     4.入力されたパラメータと現在のインスタンス(*this)が同じインスタンスであるかどうかを判断します.判断しないと、まず自分のメモリを解放し、付与する内容が見つからない.
 
次は2つの解法です.
    1.古典的な解法で、初級プログラマーに適しています
CMyString& CMyString::operator =(const CMyString &str)

{

    if(this == &str)

       return *this;

    

       delete []m_pData;

    m_pData =NULL;

    m_pData=new char[strlen(str.m_pData)+1);

    strcpy(m_pData,str.m_pData);

     

    return *this;

}

 
   2.異常安全性を考慮した解法は,上級プログラマーに適している
CMyString& CMyString::operator =(const CMyString &str)

{

    if(this != &str)

     {

        CMyString strTemp(str);

        

        char *Temp=strTemp.m_pData;

        strTemp.m_pData=m_pData;

        m_pData=Temp;

     }

    return *this;

}

第2の方法では、strTempのm_pData指向前m_pDataのメモリは、if文をスキップすると、構造関数を呼び出して前のインスタンスのメモリを解放します.
また、CMyStringのコンストラクション関数newでメモリの割り当てに失敗した場合、元のインスタンスのステータスが変更されていないことを保証し、異常なセキュリティを保証します.
 
このインスタンスのすべてのソースコード:
// AssignmentOperator.cpp : Defines the entry point for the console application.

//



// 《 Offer—— 》 

//



#include "stdafx.h"

#include <string>



class CMyString

{

public:

    CMyString(char* pData = NULL);

    CMyString(const CMyString& str);

    ~CMyString(void);



    CMyString& operator = (const CMyString& str);



    void Print();

      

private:

    char* m_pData;

};



CMyString::CMyString(char *pData)

{

    if(pData == NULL)

    {

        m_pData = new char[1];

        m_pData[0] = '\0';

    }

    else

    {

        int length = strlen(pData);

        m_pData = new char[length + 1];

        strcpy(m_pData, pData);

    }

}



CMyString::CMyString(const CMyString &str)

{

    int length = strlen(str.m_pData);

    m_pData = new char[length + 1];

    strcpy(m_pData, str.m_pData);

}



CMyString::~CMyString()

{

    delete[] m_pData;

}



CMyString& CMyString::operator = (const CMyString& str)

{

    if(this == &str)

        return *this;



    delete []m_pData;

    m_pData = NULL;



    m_pData = new char[strlen(str.m_pData) + 1];

    strcpy(m_pData, str.m_pData);



    return *this;

}



// ==================== ====================

void CMyString::Print()

{

    printf("%s", m_pData);

}



void Test1()

{

    printf("Test1 begins:
"); char* text = "Hello world"; CMyString str1(text); CMyString str2; str2 = str1; printf("The expected result is: %s.
", text); printf("The actual result is: "); str2.Print(); printf(".
"); } // void Test2() { printf("Test2 begins:
"); char* text = "Hello world"; CMyString str1(text); str1 = str1; printf("The expected result is: %s.
", text); printf("The actual result is: "); str1.Print(); printf(".
"); } // void Test3() { printf("Test3 begins:
"); char* text = "Hello world"; CMyString str1(text); CMyString str2, str3; str3 = str2 = str1; printf("The expected result is: %s.
", text); printf("The actual result is: "); str2.Print(); printf(".
"); printf("The expected result is: %s.
", text); printf("The actual result is: "); str3.Print(); printf(".
"); } int _tmain(int argc, _TCHAR* argv[]) { Test1(); Test2(); Test3(); return 0; }

 
参考書『剣指offer』