剑指offer--面试题1

     为了准备实习面试,最近开始看《剑指offer》, 以前挺反感这种有投机性质的书。但是为了拿到个好offer,也顾不了那么多了。

     第一道题是考  基础知识 里面的编程语言。C++基本是每个应聘者都需要掌握的语言吧,因为一般在草纸上写代码都是C或者C++的。

     对于C++来说,类的定义和结构,以及继承,派生,多态是面试中常被问到的, 而面试题1就考察了应试者对C++中赋值运算符的理解。  

  一般来说,C++中的一个空类会默认生成以下函数。

1:默认构造函数
2:默认拷贝构造函数
3:默认赋值操作符
4:默认虚构函数
5:取值操作符.

class A
{
A();
A(const A &lhs);
A& operator=(const A &lhs);
~A();
A* opeator&();
}
至于每个函数的作用 《C++ primer》中有很详细的讲解。

而这里需要强调的是 sizeof(A) = 1, 这是因为我们声明类型的实例时,它必须在内存中占有一定的空间,至于占多少内存,是由编译器决定的,VS中每个空类型的实例占用1字节的空间。

面试题1: 如下为类型CMyString的声明,请为该类型添加赋值运算符函数
class CMyString
{
  public:
      CMyString(char * pData = NULL);
      CMyString(const CMyString & str);
      ~CMyString(void);
  private:
      char * pData;
}

  解决这个问题需要考虑几点:

  1. 把返回值的类型声明为该类型的引用, 因为函数本身是不能作为左值的。所以如果返回类型设为void,应用该赋值运算符将不能做连续赋值,如 str1 = str2 = str3

  2. 传入参数的类型声明为引用,这样可以避免形参到实参的一次拷贝,提高带代码的效率。

  3. 记得释放实例本身占用的内存,否则会造成内存泄露

  4. 记得判断传入的参数和当前实例不是同一个实例,如果是同一个,则不进行赋值操作,直接返回。

  考虑到这几个问题,我们代码就出来了:

 1  1 CMyString & CMyString::operator = (const CMyString & str)
 2  2 {
 3  3      if(*this == str)     //当然类定义中要重载==。 而且关系运算符最好以友元函数的形式重载
 4  4              return * str;
 5  5      
 6  6      delete [] m_Ddata;    
 7  7      m_pData = NULL; //释放过后的内存指针要指向=NULL,防止产生野指针
 8  8      m_ pData = new char[strlen(str.m_pData)+1];  //字符串默认最后会加上'\0'作为结束,所以要多申请1个空间
 9  9      strcpy(m_pData, str); 
10 10                 
11 11 }

     写出这样的代码对于初级程序员来说就已经足够了,当然书中后面也给出了考虑异常安全性的解法, 这里就不列出了。

     另外,书中前面还给出了个程序改错题,错误的原始是因为拷贝构造函数使用的传值操作,而不是传引用。 我们都知道传值操作会进行一次形参到实参的拷贝,拷贝的过程中会调用类的拷贝构造函数,这样就会造成永无休止的递归调用,直到栈溢出。

 

posted on 2013-05-14 22:25  iamccme  阅读(586)  评论(0编辑  收藏  举报

导航