【劍指offer】2.2 編程語言

面試題1:賦值運算符函數

題目:如下爲類型CMyString的聲明,請爲該類型添加賦值運算符函數。

class CMyString
{
public:
    CMyString(char* pData = NULL);
    CMyString(const CMyString& str);
    ~CMyString();
private:
    char* m_pData;
};

解答:

class CMyString
{
public:
    CMyString(const char* pData = NULL);
    CMyString(const CMyString& str);
    CMyString& operator=(const CMyString& str);
    ~CMyString();
private:
    char* m_pData;
};

//構造函數:自定義類型的初始化
CMyString::CMyString(const char* str)
{
	//預防淺拷貝,重新申請內存
	int len = strlen(str);
	m_pData = new char[len + 1];
	strcpy(m_pData,str);
}

//拷貝構造函數:用一個已存在的對象構造一個正在生成的對象
CMyString::CMyString(const CMyString& str)//必須傳引用,否則會造成死遞歸。因爲傳參的過程也是一次拷貝構造
{
	//預防淺拷貝
	int len = strlen(str.m_pData);
	m_pData = new char[len + 1];
	strcpy_s(m_pData,len+1,str.m_pData);
}

//等號運算符重載:用一個已存在對象給另一個已存在的對象賦值
CMyString& CMyString::operator=(const CMyString& str)//返回值爲自身引用,以便連續賦值
{
	//防止自賦值
	if(this == &str)
	{
		return *this;
	}

	//防止內存泄漏
	delete []m_pData;
	m_pData = NULL;

	//預防淺拷貝
	int len = strlen(str.m_pData);
	m_pData = new char[len + 1];
	strcpy_s(m_pData,len+1,str.m_pData);

	return *this;

	//異常安全情況下
	//if(this != &str)
	//{
	//	  CMyString strTemp(str);
	//	  char* pTemp = strTemp.m_pData;
	//	  strTemp.m_pData = this->m_pData;
	//	  this->m_pData = pTemp;
	//}
	//return *this;
}

//析構函數:在對象生存期滿之後默認調用的成員方法,用於釋放地址空間。不可重載
CMyString::~CMyString()
{
	delete []m_pData;
}

面試題2:實現Singleton模式

題目:設計一個類,我們只能生成該類的一個實例。

解答:用懶漢模式下的單例模式和雙檢鎖機制來實現。單例模式下一個類只允許生成一個實例,通過把構造函數設爲私有來實現。

單例模式特點:1.私有的構造函數;2.私有的靜態單例對象;3.公有的靜態方法。

#include <iostream>
#include <pthread.h>

using namespace std;

class Singleton
{
private:
	Singleton() {}
	Singleton(const Singleton& obj);
	Singleton& operator=(const Singleton& obj);
	static pthread_mutex_t mutex;
	static Singleton* _instance;
public:
	static Singleton* getInstance()
	{
		if(NULL == _instance)
		//如果不判空則每次進來都要加鎖,影響效率
		{
			pthread_mutex_lock(&mutex);//線程安全
			if(NULL == _instance)//避免創建多個對象
			{
				Singleton *p = new Singleton();
				_instance = p;
			}
			pthread_mutex_unlock(&mutex);
		}

		return _instance;
	}
};

Singleton* Singleton::_instance = NULL;
pthread_mutex_t Singleton::mutex = PTHREAD_MUTEX_INITIALIZER;

int main()
{
	Singleton* s1 = Singleton::getInstance();
	Singleton* s2 = Singleton::getInstance();
	if(s1 == s2)
	{
		cout << "yes" << endl;
	}
	else
	{
		cout << "no" << endl;
	}

	return 0;
}

懶漢模式:在真正用到的時候纔去實例化對象。

餓漢模式:Singleton* Singleton::_instance = new Singleton();

    在實例化_instance時,直接調用類的構造函數,顧名思義,在還未使用變量時,已經對_instance進行賦值,就像很飢餓的感覺。這種模式在多線程環境下是線程安全的,因爲不存在多線程實例化的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章