面試題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進行賦值,就像很飢餓的感覺。這種模式在多線程環境下是線程安全的,因爲不存在多線程實例化的問題。