面试题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进行赋值,就像很饥饿的感觉。这种模式在多线程环境下是线程安全的,因为不存在多线程实例化的问题。