剣指Offer読書ノート(1)

2269 ワード

2章
2.2プログラミング言語
1.C++では空のタイプを定義し、そのタイプに対してsizeof()を1とし、そのタイプを宣言するときは、コンストラクタとコンストラクタの結果が加わっても1のメモリに一定の空間を占有する必要があります.コンパイラは、1つのタイプに仮想関数が含まれていることを発見した場合、そのタイプの仮想関数テーブルを生成し、そのタイプの各インスタンスにポインタを追加します.sizeof()を求めると、32ビットで4,64ビットで8になります.
2.C++では、struct定義のタイプではpublicがデフォルト、classではprivateがデフォルトです.
3.代入演算子関数
演算子関数を定義するときは、次のことを考慮します.
A.戻り値のタイプを参照として宣言し、終了前にインスタンス自体の参照(すなわち*this)を返して、連続的な付与の問題を解決するかどうか.
B.入力パラメータのタイプを常引用として宣言するかどうか、入力パラメータが修正され、再帰構造関数がオーバーヘッドを減らすことを避ける.
C.インスタンス自体のメモリを解放し、メモリ漏洩を防止するか.
D.挿入されたパラメータと現在のインスタンスが同一のインスタンスであるか否かを判定する.
CMySring& CMyString::operator=(const CMySrting &str)
{
	if (this == &str)
	{
		return *this;
	}							

	delete[] m_pData;
	m_pData = NULL;

	m_pData = new char(sizeof(str.m_pData) + 1);
	strcpy(m_pData, str.m_pData);
	return *this;
}
メモリ不足によるnew char放出異常、m_pDataは空のポインタになり、プログラムがクラッシュしやすくなります.すなわち、付与演算子関数の内部に異常が投げ出されると、CMyStringのインスタンスは有効な状態を維持しなくなり、異常なセキュリティの原則に反する.
代入演算子関数での異常なセキュリティを解決するには、次の手順に従います.
(1)newで新しいメモリを割り当て、deleteで既存のコンテンツを解放する
(2)一時インスタンスを作成し、一時インスタンスと元のインスタンスを交換する
//    
CMyString& CMyString::operator=(const CMyString &str)
{
	if (this != str)
	{
		CMyString strTemp(str);
		char* pTemp = strTemp.m_pData;
		strTemp.m_pData = m_pData;	
		m_pData = pTemp;			
	}
	return *this;
}
#pragma once
#include 

class MyString
{
public:
	MyString(char* pdata = NULL)
	{
		if (pdata == NULL)
		{
			_data = new char[1];
			*_data = '\0';
		}
		else
		{
			int length = strlen(pdata);
			_data = new char[length + 1];
			strcpy(_data, pdata);
		}
	}
	MyString (const MyString& str)
	{
		int length = strlen(str._data);
		_data = new char[length + 1];
		strcpy(_data, str._data);
	}
	MyString& operator=(const MyString& str)
	{
		if (this == &str)
			return *this;

		delete[] _data;
		_data = NULL;

		_data = new char[strlen(str._data) + 1];
		strcpy(_data, str._data);

		return *this;
	}

	void PrintMyString()
	{
		printf("%s", _data);
	}
protected:
	char* _data;
};

void TestMyString()
{
	char* str = "hello world.";
	MyString str1;
	str1 = str;
	str1.PrintMyString();
	MyString str2(str1);
	str2.PrintMyString();
}