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

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

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

class FinalClass
{
public:
	static FinalClass* GetInstance()
	{
		return new FinalClass;
	}
 
	static void DeleteInstance(FinalClass* pInstance)
	{
		delete pInstance;
		pInstance = NULL;
	}
private:
	FinalClass() {}  //私有的构造函数
	~FinalClass() {} //私有的析构函数
};
       问题17:设计一个类,我们只能生成该类的一个实例

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

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

//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;
}

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

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次。代码如下:

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修饰。下面给出一个实现。

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类型,以使得其返回值不为"左值"。


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值