有點意思的C/C++問題及解答:16-20
問題16:在C++中定一個不能被繼承的類
解法:容易想到的就是將這個類的建構函式和解構函式都設為私有的。這樣繼承的類就無法呼叫父類的建構函式和解構函式,編譯時就會報錯。但是不能被繼承的類如何產生物件呢?可以利用靜態函式,它與類的物件無關,可以直接通過類的作用域直接呼叫。
[cpp] view plain copy print ?
- class FinalClass
- {
- public:
- static FinalClass* GetInstance()
- {
- return new FinalClass;
- }
- static void DeleteInstance(FinalClass* pInstance)
- {
- delete pInstance;
- pInstance = NULL;
- }
- private:
- FinalClass() {} //私有的建構函式
- ~FinalClass() {} //私有的解構函式
- };
解法:其實就是設計模式中的單例模式。這裡給出兩種方式。
方式一:類似問題16,將建構函式和解構函式定義為私有的,定義一個靜態的類物件指標。通過靜態函式進行初始化。
[cpp] view plain copy print ?
- //Single.h定義
- #pragma once
- class Singleton
- {
- public:
- static Singleton* GetInstance();
- private:
- Singleton();
- ~Singleton();
- static Singleton *singleton;
- };
- //Singleton.cpp定義
- Singleton* Singleton::singleton = NULL; //靜態成員初始化
- Singleton::Singleton()
- {
- }
- Singleton::~Singleton()
- {
- }
- Singleton* Singleton::GetInstance()
- {
- if(singleton == NULL)
- singleton = new Singleton();
- return singleton;
- }
方式二:利用區域性靜態變數只初始化一次的性質,可以這樣來實現。
[cpp] view plain copy print ?
- class Singleton
- {
- private:
- Singleton(){}
- public:
- static Singleton* GetInstance()
- {
- static Singleton singleton; //區域性靜態變數
- return &singleton;
- }
- };
問題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次。程式碼如下:
[cpp] view plain copy print ?
- int C100_Solution1()
- {
- int num = 0;
- for(int x = 0; x <= 100; x++)
- for(int y = 0; y <= 50; y++)
- for(int z = 0; z <= 20; z++)
- num += ((x + 2 *y + 5 *z) == 100);
- return num;
- }
- int C100_Solution2()
- {
- int num = 0;
- for (int i = 0; i <= 100;i += 5)
- num += (i + 2)/2;
- return num;
- }
問題19:實現一個strcpy函式。
解答:看似簡單,其實考查的是基本功。需要注意這麼幾點:(1)指標為空判斷。(2)實現鏈式操作。(3)C的字串以'\0'結尾。(4)源指標加const修飾。下面給出一個實現。
[cpp] view plain copy print ?- char* strcpy(char *pDest, const char *pSrc)
- {
- assert(pDest!=NULL && pSrc!=NULL);
- char* tmp = pDest;
- while((*pDest++ = *pSrc++) != '\0')
- ;
- return tmp;
- }
問題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型別,以使得其返回值不為"左值"。