• 第67课 经典问题解析五


    面试问题:

    编写程序判断一个变量是不是指针?

    指针的判别:

    匹配顺序示例:

     可以看到匹配顺序符合我们的结论。

     

    定义一个函数模板和一个同名的变参函数,给的参数如果是指针,编译器会先匹配模板。不是指针的话只能匹配变参函数。

    实验:

    第41行我们看到输出了非法指令,这是为什么呢,因为变参函数是C语言的特性,41行匹配到了变参函数,而C语言中没有对象的概念,因此,我们在41行传入t对象会报非法指令的错误。

    缺陷分析:

     只让编译器匹配,但是不运行,以用来解决上述函数调用的问题:使用sizeof

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 class Test
     7 {
     8 public:
     9     Test()
    10     {
    11     }
    12     virtual ~Test()
    13     {
    14     }
    15 };
    16 
    17 template
    18 <typename T>
    19 char IsPtr(T* v) // match pointer
    20 {
    21     return 'd';
    22 }
    23 
    24 int IsPtr(...)  // match non-pointer
    25 {
    26     return 0;
    27 }
    28 
    29 #define ISPTR(p) (sizeof(IsPtr(p)) == sizeof(char))
    30 
    31 int main(int argc, char *argv[])
    32 {
    33     int i = 0;
    34     int* p = &i;
    35     
    36     cout << "p is a pointer: " << ISPTR(p) << endl;    // true
    37     cout << "i is a pointer: " << ISPTR(i) << endl;    // false
    38     
    39     Test t;
    40     Test* pt = &t;
    41     
    42     cout << "pt is a pointer: " << ISPTR(pt) << endl;    // true
    43     cout << "t is a pointer: " << ISPTR(t) << endl;    // false
    44     
    45     return 0;
    46 }

     运行结果如下:

    面试问题:

    如果构造函数中抛出异常会发生什么?

     

     实验:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 class Test
     7 {
     8 public:
     9     Test()
    10     {
    11         cout << "Test()" << endl;
    12         
    13         throw 0;
    14     }
    15     virtual ~Test()
    16     {
    17         cout << "~Test()" << endl;
    18     }
    19 };
    20 
    21 
    22 int main(int argc, char *argv[])
    23 {
    24     Test* p = reinterpret_cast<Test*>(1);
    25     
    26     try
    27     {
    28         p = new Test();
    29     }
    30     catch(...)
    31     {
    32         cout << "Exception..." << endl;
    33     }
    34     
    35     cout << "p = " << p << endl;
    36     
    37     return 0;
    38 }

    结果如下:

    可以看到28行p指针的值没有被赋值,在35行依旧打印出了1。

    在构造函数中抛出异常,new关键字是不会返回一个值的,也不会返回空指针。在这种情况下不会发生内存泄漏,Test对象的内存会被回收。

    使用内存检测工具进行检测:

     可以看到0 byte in 0 blocks,说明在程序结束时是没有内存泄漏的。

    我们将13行的throw注释掉,再次使用内存检测工具检测,结果如下:

     析构函数中的抛出异常:

    小结:

     

  • 相关阅读:
    窗口
    DataTemplateSelector
    CompositeCollection
    Drawing
    模板
    集合视图
    绑定
    动画
    【数据结构初学】(java实现篇)——队列(转)
    慕课学习手记!(完成查找书籍小程序~)
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9601324.html
Copyright © 2020-2023  润新知