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

07-14 00:12