franksunny的个人技术空间
获得人生中的成功需要的专注与坚持不懈多过天才与机会。 ——C.W. Wendte

网讯笔试归来

昨天去网讯(杭州)笔试了,做了下笔试题,感觉题目都不难,但是自己做的的确不怎么样,估计是没机会去了,不过暂时还是先把几道自己还记得的题目,写出来,总结下,以做复习。

1、  要求自己实现 String 类,给出了 String 类的以下头文件类声明

class String

{

public:

       String(const char *m_char = NULL);

       String(const String & Str);

       String& operator = (const String &Str);

       ~String();

private:

       char * m_Data;

};

 

关于 String 类的笔试题,以前看林锐的随笔时听说他在微软面试时曾碰到那么一道题目,我自己也没有真的下笔去做过,平常都是拿来就用的,这次自己碰到,才知道会死得那么惨,反正编得不堪入目(我就不拿出来献丑了),下面是我回来后,自己重新写的答案。

String::String(const char* m_char)

{

       int m_nLength = strlen(m_char) + 1;

       if (m_Data != NULL)

       {

              delete [] m_Data;

              m_Data = NULL;

       }// 以上判断是否必要 ??

       m_Data = new char[m_nLength];

       memcpy(m_Data, m_char, m_nLength);

}

 

String::String(const String &Str)

{

       int m_nLength = strlen(Str.m_Data) + 1;// 以前真的不知道,原来对象的私有变量

// 在类的实现代码中也是可以访问的

       if (m_Data != NULL)

       {

              delete [] m_Data;

              m_Data = NULL;

       }// 以上判断是否必要 ??

       m_Data = new char[m_nLength];

       memcpy(m_Data, Str.m_Data, m_nLength);

}

 

String& String::operator = (const String& Str) 

{

       if(this == &Str)

              return *this;

 

       int m_nLength = strlen(Str.m_Data) + 1;

       if (m_Data != NULL)

       {

              delete [] m_Data;

              m_Data = NULL;

       }// 以上判断是否必要 ??

      

       m_Data = new char[m_nLength];

       memcpy(m_Data, Str.m_Data, m_nLength);

       return *this;

}

 

String::~String()

{

       if (m_Data != NULL)

       {

              delete [] m_Data;

              m_Data = NULL;

       }

}

 

2、  关于内存分配

这个题目很简单,就给了一个函数,然后问函数内的局部变量存放在哪里,我也不知道为什么当时会选择 heap( ) ,下面再把几个概念罗列出来:

1.            堆区( heap ):由程序员申请分配和释放,属动态内存分配方式,若程序员不释放,程序结束时可能会由 OS 回收。不过这个内存分配很容易引起问题,如果申请的内存不释放就会造成内存泄漏;如果释放的不是所要释放的内存,则轻者引起程序运行结果出错,重者系统崩溃。

2.            栈区( stack ):编译器自动分配释放,存放函数的形参值、局部变量的值,也是属于动态内存分配方式,它由系统分配,所以执行效率也高,不过自由度小,声明时就得决定其具体大小。

3.            全局区(静态区)( static ):全局变量和静态变量的存储是放在一块的,而且初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放,所以也不会造成内存问题。

除了以上的变量外,还有两类存放位置,文字常量区和程序代码区,两者都是由系统分配和释放,且文字常量区和前面三区合成为程序数据区,与程序代码区相对应。

3、  关于类继承的构造和析构函数

class Base

{

public:

       Base(){cout<< "Base" <<endl;};

       ~Base(){cout<<"~Base"<<endl;};

protected:

private:

};

 

class First:public Base

{

public:

       First(){cout << "First" << endl;};

       ~First(){cout << "~First" <<endl;};

};

 

int main()

{

       Base *a = new First;

       delete a;

}

问程序的输出会是什么?

结果很简单,也就是 Base

                               First

                   ~Base

其它还有一个关于 & 的题目,把我搞的云里雾里的,还要再看些东西才知道怎么来解释。

posted on 2007-03-04 21:53 frank.sunny 阅读(3359) 评论(10)  编辑 收藏 引用 所属分类: C/C++学习和实践

FeedBack:
# re: 网讯笔试归来
2007-03-04 23:01 | 郁郁寡欢
第一,你的背景色太要命了,你自己看一分钟试试!
第二,
===================
if (m_Data != NULL)
{
delete [] m_Data;
m_Data = NULL;

}
====================
你同样的代码重复次数太多了,就不能做成一个函数吗?

第三,每次delete然后new,也可以做一些判断,不用delete直接strcpy吧,不过这属于优化了,对于笔试应该影响不大吧?  回复  更多评论
  
# re: 网讯笔试归来
2007-03-04 23:09 | SmartPtr
if (m_Data != NULL)
{
delete [] m_Data;
m_Data = NULL;
}

***************************************
因为C++delete一个NULL指针是合法的。(可能编译器delete的时候就对NULL进行了特殊处理),所以无需判断,直接写:
delete [] m_Data;
m_Data = NULL;   回复  更多评论
  
# re: 网讯笔试归来
2007-03-04 23:19 | DC
前面2个Constructor,肯定是不需要
if (m_Data != NULL)
{
delete [] m_Data;
m_Data = NULL;
}
而且是应该直接付值m_Data = NULL;先,否则,程序在这里会有异常!因为m_Data的初值不会为0。


后面的String& String::operator = (const String& Str)需要判断m_Data != NULL以判断是否需要释放内存。


你现在的答案还是蛮多漏洞。  回复  更多评论
  
# re: 网讯笔试归来
2007-03-05 17:01 | frank.sunny
谢谢如上各位指点,我以后用代码时背景改成灰色好了。

根据大家的建议,我后来改了下代码,改成如下方式:
String::String(const char* m_char) :m_Data(NULL)
{
int m_nLength = strlen(m_char) + 1;
m_Data = new char[m_nLength];
strcpy(m_Data, m_char);
}

String::String(const String &Str) : m_Data(NULL)
{
int m_nLength = strlen(Str.m_Data) + 1;
m_Data = new char[m_nLength];
strcpy(m_Data, Str.m_Data);
}
个人还参考了下memcpy和strcpy的区别,也没说哪个执行效率高些,当然能简化就简化,  回复  更多评论
  
# re: 网讯笔试归来
2007-03-05 19:00 | tx7do
memcpy是汇编实现的,效率还是很高的。  回复  更多评论
  
# re: 网讯笔试归来
2007-03-05 21:40 | badtiger
长见识了!谢谢各位  回复  更多评论
  
# re: 网讯笔试归来
2007-03-05 22:27 | frank.sunny
@tx7do

的确如你所说,我也长见识了,呵呵
谢谢你
  回复  更多评论
  
# re: 网讯笔试归来
2007-03-08 17:33 | ZHua
一同学习阿 呵呵  回复  更多评论
  
# re: 网讯笔试归来
2008-10-14 18:17 | 猫猫咬
这样实现String类太低效了,应该一下分配出一定的空间(大于初始化的字符串长度),4字节的倍数会更好些。  回复  更多评论
  
# re: 网讯笔试归来
2008-10-14 18:25 | 万连文
这种问题,我的答案是 copy mfc的CString,ok?  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理



常用链接

留言簿(13)

随笔分类

个人其它博客

基础知识链接

最新评论

阅读排行榜

评论排行榜