有点意思的C/C++问题及解答:16-20

问题16:在C++中定一个不能被继承的类

       解法:容易想到的就是将这个类的构造函数和析构函数都设为私有的。这样继承的类就无法调用父类的构造函数和析构函数,编译时就会报错。但是不能被继承的类如何产生对象呢?可以利用静态函数,它与类的对象无关,可以直接通过类的作用域直接调用。

  1. class FinalClass  
  2. {  
  3. public:  
  4.     static FinalClass* GetInstance()  
  5.     {  
  6.         return new FinalClass;  
  7.     }  
  8.    
  9.     static void DeleteInstance(FinalClass* pInstance)  
  10.     {  
  11.         delete pInstance;  
  12.         pInstance = NULL;  
  13.     }  
  14. private:  
  15.     FinalClass() {}  //私有的构造函数  
  16.     ~FinalClass() {} //私有的析构函数  
  17. };  
       问题17:设计一个类,我们只能生成该类的一个实例

    解法:其实就是设计模式中的单例模式。这里给出两种方式。

    方式一:类似问题16,将构造函数和析构函数定义为私有的,定义一个静态的类对象指针。通过静态函数进行初始化。

  1. //Single.h定义  
  2. #pragma once  
  3. class Singleton    
  4. {  
  5. public:  
  6.     static Singleton* GetInstance();  
  7. private:  
  8.     Singleton();  
  9.     ~Singleton();  
  10.     static Singleton *singleton;  
  11. };  
  12. //Singleton.cpp定义  
  13. Singleton* Singleton::singleton = NULL; //静态成员初始化  
  14. Singleton::Singleton()  
  15. {  
  16. }  
  17. Singleton::~Singleton()  
  18. {  
  19. }  
  20. Singleton* Singleton::GetInstance()  
  21. {  
  22.     if(singleton == NULL)  
  23.         singleton = new Singleton();  
  24.     return singleton;  
  25. }  

   方式二:利用局部静态变量只初始化一次的性质,可以这样来实现。

  1. class Singleton    
  2. {    
  3. private:       
  4.     Singleton(){}  
  5. public:                    
  6.     static Singleton* GetInstance()    
  7.     {    
  8.         static Singleton singleton; //局部静态变量  
  9.         return &singleton;  
  10.     }    
  11. };  

       问题18:写一个程序,要求功能,求出用1、2、5这三个数不同个数组合的和为100的组合数。如100个1是一个组合,20个5是另外一个组合。用C++实现。

       解法:最简单的用穷举法,三层循环就可以解决了。代码如下,这样效率太低了。循环次数为101 * 51 * 21。 这其实就是个数学问题,就是求 x + 2y + 5z = 100解的个数。变化一下,x + 5z = 100 - 2y,这个式子表明 x + 5y只能是偶数。以z为循环变量,有下述规律。

         z=0, x=100, 98, 96, ... 0
      z=1, x=95, 93, ..., 1
      z=2, x=90, 88, ..., 0
      z=3, x=85, 83, ..., 1
      z=4, x=80, 78, ..., 0
      ......
      z=19, x=5, 3, 1
      z=20, x=0

      因此,组合总数为100以内的偶数+95以内的奇数+90以内的偶数+...+5以内的奇数+1,
即为:(51+48)+(46+43)+(41+38)+(36+33)+(31+28)+(26+23)+(21+18)+(16+13)+(11+8)+(6+3)+1

      第二种方法的循环次数仅为21次。代码如下:

  1. int C100_Solution1()  
  2. {  
  3.     int num = 0;  
  4.     for(int x = 0; x <= 100; x++)  
  5.         for(int y = 0; y <= 50; y++)  
  6.             for(int z = 0; z <= 20; z++)  
  7.                 num += ((x + 2 *y + 5 *z) == 100);  
  8.     return num;  
  9. }  
  10.   
  11. int C100_Solution2()  
  12. {  
  13.     int num = 0;  
  14.     for (int i = 0; i <= 100;i += 5)  
  15.         num += (i + 2)/2;  
  16.     return num;  
  17. }  

       问题19:实现一个strcpy函数。

       解答:看似简单,其实考查的是基本功。需要注意这么几点:(1)指针为空判断。(2)实现链式操作。(3)C的字符串以'\0'结尾。(4)源指针加const修饰。下面给出一个实现。

  1. char* strcpy(char *pDest, const char *pSrc)  
  2. {  
  3.     assert(pDest!=NULL && pSrc!=NULL);  
  4.     char* tmp = pDest;  
  5.     while((*pDest++ = *pSrc++) != '\0')  
  6.         ;  
  7.     return tmp;  
  8. }  

       问题20:static和const关键字尽可能多的作用。

    static关键字至少有下列作用: 
   (1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值; 
  (2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问; 
  (3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内; 
  (4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝; 
  (5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。 

     const关键字至少有下列作用: 
  (1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了; 
  (2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const; 
  (3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值; 
  (4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量; 
  (5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为"左值"。

猜你喜欢

转载自blog.csdn.net/nk_wang/article/details/44066873