1、面试问题
编写程序判断一个变量是不是指针。
2、指针的判别
— C++中依然支持 C语言中的可变参数函数
— C++ 编译器的匹配调用优先级
1、重载函数
2、函数模板
3、变参函数(接收任意多的参数)
#include <iostream>
using namespace std;
void test(int i) //优先级第一
{
cout << "void test(int i)" << endl;
}
template <typename T>
void test(T t) //优先级第二
{
cout << "void test(T t)" << endl;
}
void test(...) //优先级第三
{
cout << "void test(...))" << endl;
}
int main()
{
int i = 0;
test(i);
return 0;
}
注释前两个函数得出的结果:
- 思路:
— 将变量分为两类:指针和非指针
— 编写函数:
指针调用时返回 true;
非指针调用时返回 false;
#include <iostream>
#include <string>
using namespace std;
class Test
{
public:
Test()
{
}
~Test()
{
}
};
template <typename T>
bool isPtr(T* p)
{
return true;
}
bool isPtr(...)
{
return false;
}
int main()
{
int i = 0;
int* p = &i;
cout << "it is a pointer: " <<isPtr(p) << endl;
cout << "it is a pointer: " << isPtr(i) << endl;
Test test;
Test* t = &test;
cout << "it is a pointer: " << isPtr(t) << endl;
cout << "it is a pointer: " << isPtr(test) << endl; //变参函数是C语言中的东西
return 0;
}
非法指令原因:变参函数当参数是对象的时候会出错,因为变参函数是C语言里面的东西。变参函数根本不知道对象是什么东西。
存在缺陷:
变参函数无法解析对象参数,可能造成程序崩溃
进一步的挑战:
如何让编译器精确匹配函数,但不进行实际的调用?
解决方案:sizeof
#include <iostream>
#include <string>
using namespace std;
class Test
{
public:
Test()
{
}
~Test()
{
}
};
template <typename T>
char isPtr(T* p)
{
return 'c';
}
int isPtr(...)
{
return 0;
}
#define ISPTR(p) (sizeof(isPtr(p)) == sizeof(char))
int main()
{
int i = 0;
int* p = &i;
cout << "it is a pointer: " << ISPTR(p) << endl;
cout << "it is a pointer: " << ISPTR(i) << endl;
Test test;
Test* t = &test;
cout << "it is a pointer: " << ISPTR(t) << endl;
cout << "it is a pointer: " << ISPTR(test) << endl;
return 0;
}
2、面试问题
如果构造函数中抛出异常会发生什么情况?
- 构造函数中抛出异常
— 构造过程立即停止
— 当前对象无法生成
— 析构函数不会被调用
— 对象占用的空间立即收回(重点) - 工程项目中的建议
— 不要在构造函数中抛出异常
— 当构造函数可能产生异常时,使用二阶构造模式
#include <iostream>
#include <string>
using namespace std;
class Test
{
public:
Test()
{
cout << "Test()" << endl;
throw 0;
}
~Test()
{
cout << "~Test()" << endl;
}
};
int main()
{
Test* p = reinterpret_cast<Test*>(1);
try
{
p = new Test();
}
catch (...)
{
cout << "Exception" << endl;
}
cout << p << endl;
return 0;
}
在构造函数中抛出异常的情况下,new
关键字是不会返回一个地址值的,连空指针都不会返回。你可以看到这个 p 指针指向的地址还是我们开始的 1 地址处。
- 析构中的异常
避免在析构函数中抛出异常
析构函数的异常将导致:对象所使用的资源无法完全释放。
小结:
- C++中依然支持变参函数
- 变参函数无法很好的处理对象参数
- 利用函数模板和变参函数能够判断指针变量
- 构造函数和析构函数中不要抛出异常