剑指offer经典题(利用C++的特性)
2016-05-24 20:50
337 查看
1.题目:求1+2+…..+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字
解法一:利用构造函数
解法二:利用虚函数求解
如何把一个数值变量n转化为布尔值。如果对n连续做两次反运算,即!!n,那么非零的n转换成true,0转换成false
解法三:利用函数指针求解
在C语言的编程环境中,不能使用虚函数,此时可以用函数来模拟
解法四:利用模板类型求解
2.题目:不用加减乘除做加法运算
异或和加法就差一个进位
3.题目:用C++设计一个不能被继承的类
解法一:把构造函数设为私有函数
解法二:利用虚拟继承:实现一个与一般的类型相比除了不能被继承之外其他用法一样的类型,
这个SealedClass2 使用起来和一般的类型没有区别,可以在栈上和队上创建实例,尽管类MakeSealed的构造函数和析构函数都是私有的,但由于类SealedClass2是它的友元类型,因此在SealedClass2中调用MakeSealed的构造函数和析构函数都不会引起编译错误
但是试图从SealClass2中继承一个类并创建它的实例时候,却不能通过编译。
由于类SealedClass2是从类MakeSealed虚继承过来的,在调用Try的构造函数的时候,会跳过SealedClass2而直接调用MakeSealed构造函数,Try并不是MakeSealed的友元类型,因此不能调用它的私有构造函数。
这种的可移植性不好,目前Gcc中还不支持模板参数类型作为友元类型
解法一:利用构造函数
class Temp { public: Temp() {++N;Sum+=N} //static void Reset(){N=0;Sum=0;} static unsigned int GetSum(){ return Sum;} private: static unsigned int N; static unsigned int Sum; }; unsigned int Temp::N=0; unsigned int Temp::Sum=0; unsigned int Sum_Solution1(unsigned int n) { //Temp::Reset(); Temp *a=new Temp ; delete []a; a=NULL; return Temp::GetSum(); }
解法二:利用虚函数求解
如何把一个数值变量n转化为布尔值。如果对n连续做两次反运算,即!!n,那么非零的n转换成true,0转换成false
class A; A* Array[2]; class A { public: virtual unsigned int Sum(unsigned int n) { return 0; } }; class B:public A { public: virltual unsigned int Sum(unsigned int n) { return Array[!!n]->Sum(n-1)+n; } }; int Sum_Solution2(int n) { A a; B b; Array[0]=&a; Array[1]=&b; int value=Array[1]->Sum(n); return value; } //这种思路就是用虚函数来实现函数的选择,当n不为零,调用B::Sum,当n等于0时,调用函数A::Sum
解法三:利用函数指针求解
在C语言的编程环境中,不能使用虚函数,此时可以用函数来模拟
typedef unsigned int (*fun) (unsigned int); unsigned int Solution3_Teminator(unsigned int n) { return 0; } unsigned int Sum_Solution3(unsigned int n) { static fun f[2]={Solution3_Teminator,Sum_Solution3}; return n+f[!!n](n-1); }
解法四:利用模板类型求解
template <unsigned int n> struct Summ_Solution4 { enum Value{N=Sum_Solution<n-1>::N+n}; }; template <>struct Sum_Solution4<1> { enum Value{N=1}; };
2.题目:不用加减乘除做加法运算
异或和加法就差一个进位
int Add(int num1,int num2) { int sum,carry; do{ sum=num1^num2; carry=(num1&num2)<<1; num1=sum; num2=carry; }while(num2!=0); return num1; }
3.题目:用C++设计一个不能被继承的类
解法一:把构造函数设为私有函数
class SealedClass1 { public: static SealedClass1 *GetInstance() { return new SealedClass1(); } static void DeleteInstance(SealedClass1* pInstance) { delete pInstance; } private: SealedClass1(){} ~SealedClass1(){} };
解法二:利用虚拟继承:实现一个与一般的类型相比除了不能被继承之外其他用法一样的类型,
template<typename T>class MakeSealed { friend T; private: MakeSealed(){} ~MakeSealed(){} } class SealedClass2:virtual public MakeSealed<SealedClass2> { public: SealedClass2(){} ~SealedClass2(){} };
这个SealedClass2 使用起来和一般的类型没有区别,可以在栈上和队上创建实例,尽管类MakeSealed的构造函数和析构函数都是私有的,但由于类SealedClass2是它的友元类型,因此在SealedClass2中调用MakeSealed的构造函数和析构函数都不会引起编译错误
但是试图从SealClass2中继承一个类并创建它的实例时候,却不能通过编译。
cpp class Try:public SealedClass2 { public: Try(){} ~Try(){} };
由于类SealedClass2是从类MakeSealed虚继承过来的,在调用Try的构造函数的时候,会跳过SealedClass2而直接调用MakeSealed构造函数,Try并不是MakeSealed的友元类型,因此不能调用它的私有构造函数。
这种的可移植性不好,目前Gcc中还不支持模板参数类型作为友元类型
相关文章推荐
- 用C++实现一个哈希表(插入,删除,查找)
- C语言小笔记
- 2015第七届蓝桥杯决赛C语言C组--五星填数(DFS)
- 【c++程序】冒泡、插入、选择、快速排序算法
- c++作业6
- 第十三周--立体类族共有的抽象类
- C++格式控制
- C语言使用函数指针跳转到程序固定地址(0x8000)执行程序的方法
- C/C++中逗号表达式的用法
- 《21天学通C++》_4 2016.5.24
- C++作业6
- C++第6次作业
- C语言:俄罗斯方块
- C++中getline()函数简介
- C++中getline()函数简介
- VC++ 通过INI配置文件,实现多国语言切换界面
- 第十三周--形状类族的中的纯虚函数
- C++中多重继承构造函数执行顺序
- 栈及实现(C语言)以及中缀式到后缀式的转换实例
- C++实验六—数组合并