一、编写程序判断一个变量是不是指针。
#include <iostream>
#include <string>
using namespace std;
void test(int i)
{
cout<<"test(int i)"<<endl;
}
template
<typename T>
void test(T v)
{
cout<<"test(T v)"<<endl;
}
void test(...)
{
cout<<"test(...)"<<endl;
}
int main(int argc, char *argv[])
{
int i=0;
test(i);
return 0;
}
test(int i)//三个函数同时存在时,优先调用重载函数
test(T v)//只有模板函数和可变参数函数时,优先调用模板函数
test(...)
实例分析1:指针判断
#include <iostream>
#include <string>
using namespace std;
template
<typename T>
bool IsPtr(T* v) // match pointer
{
return true;
}
bool IsPtr(...) // match non-pointer
{
return false;
}
int main(int argc, char *argv[])
{
int i = 0;
int* p = &i;
cout << "p is a pointer: " << IsPtr(p) << endl; // true
cout << "i is a pointer: " << IsPtr(i) << endl; // false
return 0;
}
p is a pointer: 1
i is a pointer: 0
#include <iostream>
#include <string>
using namespace std;
class Test
{
public:
Test()
{
}
virtual ~Test()
{
}
};
template
<typename T>
bool IsPtr(T* v) // match pointer
{
return true;
}
bool IsPtr(...) // match non-pointer
{
return false;
}
int main(int argc, char *argv[])
{
int i = 0;
int* p = &i;
cout << "p is a pointer: " << IsPtr(p) << endl; // true
cout << "i is a pointer: " << IsPtr(i) << endl; // false
Test t;
Test* pt = &t;
cout << "pt is a pointer: " << IsPtr(pt) << endl; // true
cout << "t is a pointer: " << IsPtr(t) << endl; // false
return 0;
}
//这里程序报错,无法判断自定义类型的指针,Test* pt = &t;这里匹配的是可变参数函数,在这个函数中不知道自定义类型是什么。
存在的缺陷:
变参函数无法解析对象参数,可能造成程序崩溃
进一步挑战:
编译在编译阶段就知道了该去匹配那个函数,而不用最终调用该函数进行实际运行。
如何让编译器精确匹配函数,但不进行实际的调用。
#include <iostream>
#include <string>
using namespace std;
class Test
{
public:
Test()
{
}
virtual ~Test()
{
}
};
template
<typename T>
char IsPtr(T* v) // match pointer
{
return 'd';
}
int IsPtr(...) // match non-pointer
{
return 0;
}
#define ISPTR(p) (sizeof(IsPtr(p)) == sizeof(char))
//sizeof(IsPtr(p))判断返回值类型大小,不用去调用该函数,进入那个函数就知道其返回值类型
int main(int argc, char *argv[])
{
int i = 0;
int* p = &i;
cout << "p is a pointer: " << ISPTR(p) << endl; // true
cout << "i is a pointer: " << ISPTR(i) << endl; // false
Test t;
Test* pt = &t;
cout << "pt is a pointer: " << ISPTR(pt) << endl; // true
cout << "t is a pointer: " << ISPTR(t) << endl; // false
return 0;
}
二、如果构造函数中抛出异常会发生什么情况?
- 构造过程立即停止
- 当前对象无法生成
- 析构函数不会被调用
- 对象所占用的空间会被立即收回。
在工程项目中的建议
不要在构造函数抛出异常
当构造函数可能产生异常时,使用二阶构造法。
#include <iostream>
#include <string>
using namespace std;
class Test
{
public:
Test()
{
cout << "Test()" << endl;
throw 0;
}
virtual ~Test()
{
cout << "~Test()" << endl;
}
};
int main(int argc, char *argv[])
{
Test* p = reinterpret_cast<Test*>(1);
try
{
p = new Test();
}
catch(...)
{
cout << "Exception..." << endl;
}
cout << "p = " << p << endl;
return 0;
}
Test()
Exception...
p = 0x1
//说明析构函数没有被调用,p = 0x1说明对象没有构造成功
避免在析构函数中抛出异常,否则对象使用的资源就无法完全释放。