Chinaunix首页 | 论坛 | 博客
  • 博客访问: 230579
  • 博文数量: 55
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 530
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-22 17:59
文章分类

全部博文(55)

文章存档

2015年(2)

2011年(1)

2010年(1)

2009年(18)

2008年(16)

2007年(17)

我的朋友

分类:

2007-07-12 22:12:27

1、虚函数的本质和实现机制
答:虚函数的本质是通过基类访问派生类定义的函数。虚函数只能借助于指针或者引用来达到多态效果。
2C++中传递函数参数的方式及他们的优缺点?
答:C++语言中,函数的参数和返回值的传递方式有三种:值传递、指针传递和引用传递。
3、重载(overload)和重写(overried,有的书也叫做“覆盖”)的区别?
答:常考的题目。从定义上来说:
重载:是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。
重写:是指子类重新定义父类虚函数的方法。
从实现原理上来说:
重载:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:function func(p:integer):integer;和function func(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的:int_func、str_func。对于这两个函数的调用,在编译器间就已经确定了,是静态的。也就是说,它们的地址在编译期就绑定了(早绑定),因此,重载和多态无关!
重写:和多态真正相关。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚绑定)。 
4、引用和指针的区别?
答:引用和指针有如下三种区别:  
        1   引用必须在声明时初始化,而指针不用;  
        2   对于NULL不能引用,而指针可以指向NULL;  
        3   引用一旦声明,对象不能改变;而指针可以随时改变指向 的对象。  
        引用能做到的,指针也可以,但指针更危险; 
 
5.改错

#include
#include
class CBuffer
{
   char * m_pBuffer;
   int m_size;
   public:
     CBuffer()
     {
       m_pBuffer=NULL;
     }
     ~CBuffer()
     {
       Free();
     }
     void Allocte(int size)   (3)     {
       m_size=size;
       m_pBuffer= new char[size];
     }
   private:
     void Free()
     {
       if(m_pBuffer!=NULL)
       {
         delete m_pBuffer;
         m_pBuffer=NULL;
       }
     }
     public:
     void SaveString(const char* pText) const
     {
       strcpy(m_pBuffer, pText);
     }
     char* GetBuffer() const
     {
       return m_pBuffer;
     }
};

void main (int argc, char* argv[])
{
   CBuffer buffer1;
   buffer1.SaveString("Microsoft");
   printf(buffer1.GetBuffer());
}

答:改正后
主要改正SaveString函数

void SaveString(const char* pText) const
{
strcpy(m_pBuffer, pText);
}
改为
void SaveString(const char* pText) (1)
{
Allocte(strlen(pText)+1); (2)
strcpy(m_pBuffer, pText);
}
原因:
(1) const成员函数表示不会修改数据成员,而SaveString做不到,去掉const声明
(2) m_pBuffer指向NULL,必须用Allocte分配空间才能赋值。
(3) 另外需要将Allocte成员函数声明为私有成员函数更符合实际

6.下来程序想打印“Welcome MSR Asia”,改正错误

#include
#include
char * GetName (void)
{
   //To return “MSR Asia” String
   char name[]="MSR Asia";
   return name;
}
void main(int argc, char* argv[])
{
   char name[32];
   //Fill in zeros into name
   for(int i=0;i<=32;i++)
   {
     name='\0';
   }
   //copy “Welcome” to name
   name="Welcome";
   //Append a blank char
   name[8]=" ";
   //Append string to name
   strcat(name,GetName());
   //print out
   printf(name);
}

答:改正后为

#include
#include
char * GetName (void)
{
   //To return “MSR Asia” String
   //char name[]="MSR Asia";       (1)  
         char *name=(char *)malloc(strlen("MSR Asia")+1);    
   strcpy(name,"MSR Asia");
   return name;
}
void main(int argc, char* argv[])
{
   char name[32];
   //Fill in zeros into name
   for(int i=0;i<=32;i++)
   {
     name='\0';
   }
   //copy “Welcome” to name
   //name="Welcome";         (2)
   strcat(name,"Welcome ");
   //Append a blank char
//   name[8]=' ';             (3)
   //Append string to name
   char *p=GetName();         (4)
   strcat(name,p);
   free (p);
   //print out
   printf(name);
}
原因:(1)在函数内部定义的变量在函数结束时就清空了,必须动态分配内存
(2)字符串赋值语句错误,应该用strcat
(3)该语句无效,可去掉
(4)定义一个指针指向动态分配的内存,用完后需用free语句释放


7.写出下面程序的输出结果

#include
class A
{
public:
   void FuncA()
   {
     printf("FuncA called\n");
   }
   virtual void FuncB()
   {
     printf("FuncB called\n");
   }
};

class B: public A
{
public:
   void FuncA()
   {
     A::FuncA();
     printf("FuncAB called\n");
   }
   virtual void FuncB()
   {
     printf("FuncBB called\n");
   }
};

void main(void)
{
   B b;
   A *pa;
   pa=&b;
   A *pa2=new A;
   b.FuncA();       (1)
   b.FuncB();       (2)  
         pa->FuncA();       (3)
   pa->FuncB();       (4)
   pa2->FuncA();       (5)
   pa2->FuncB();
   delete pa2;
}
答:
1.b.FuncA(); 输出
FuncA called
FuncAB called
2.b.FuncB();输出
FuncBB called
上两者好理解,直接调用类B的相应成员函数
3.pa->FuncA();输出
FuncA called 调用类A的FuncA()
4.pa->FuncB();输出
FuncBBcalled调用类B的FuncB(),原因是C++的动态决议机制,当基类函数声明为virtual时,指向派生类对象的基类指针来调用该函数会选择派生类的实现,除非派生类没有才调用基类的虚函数。还有一点注意的是:指向基类类型的指针可以指向基类对象也可以指向派生类对象,如pa=&b;
5. pa2->FuncA();
pa2->FuncB();输出
FuncA called
FuncB called
这也好理解,直接调用类A的相应成员函数

8.In the main() function, after ModifyString(text) is called, what’s the value of ‘text’?

#include
#include
int FindSubString(char* pch)
{
   int count=0;
   char* p1=pch;
   while(*p1!='\0')
   {
     if(*p1==p1[1]-1)
     {
       p1++;
       count++;
     }
     else
     {
       break;
     }
   }
   int count2=count;
   while(*p1!='\0')
   {
     if(*p1==p1[1]+1)
     {
       p1++;
       count2--;
     }
     else
     {
       break;
     }
   }
   if(count2==0)
     return count;
   return 0;
}

void ModifyString(char* pText)
{
   char* p1=pText;
   char* p2=p1;
   while(*p1!='\0')
   {
     int count=FindSubString(p1);
     if(count>0)
     {
       *p2++=*p1;
       sprintf(p2, "%I", count);
       while(*p2!= '\0')
       {
         p2++;
       }
       p1+=count+count+1;
     }
     else
     {
       *p2++=*p1++;
     }
   }
}
void main(void)
{
   char text[32]="XYBCDCBABABA";
   ModifyString(text);
   printf(text);
}
答:最后运行结果是XYBCDCBAIBAAP
 
 

阅读(2355) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~