[面接問題]付与演算子関数
12396 ワード
タイトル:タイプCMyStringの宣言は次のとおりです.このタイプに付与演算子関数を追加してください.
実装コードの注意点:
1.戻り値のタイプをそのタイプの参照として宣言し、関数が終了する前に自分の参照(すなわち*this)を返すかどうかは、1つの参照を返すだけで、連続的に値を割り当てることができます.例えばstr 1=str 2=str 3;
2.入力されたパラメータのタイプを定数参照として宣言するかどうか、定数参照でない場合、パラメータから実パラメータに至るまで、時間とメモリのオーバーヘッドを回避するレプリケーションコンストラクション関数が呼び出されます.また,受信インスタンスの状態を変えることを避けるためにconst修飾を加えるべきである.
3.インスタンス自体のメモリを解放するかどうか.新しいメモリを割り当てた解放自体の既存のスペースを忘れた場合、プログラムにメモリが漏洩します.
4.入力されたパラメータと現在のインスタンス(*this)が同じインスタンスであるかどうかを判断します.判断しないと、まず自分のメモリを解放し、付与する内容が見つからない.
次は2つの解法です.
1.古典的な解法で、初級プログラマーに適しています
2.異常安全性を考慮した解法は,上級プログラマーに適している
第2の方法では、strTempのm_pData指向前m_pDataのメモリは、if文をスキップすると、構造関数を呼び出して前のインスタンスのメモリを解放します.
また、CMyStringのコンストラクション関数newでメモリの割り当てに失敗した場合、元のインスタンスのステータスが変更されていないことを保証し、異常なセキュリティを保証します.
このインスタンスのすべてのソースコード:
参考書『剣指offer』
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』