美文网首页
C++ 11 新特性(八)

C++ 11 新特性(八)

作者: IT孤独者 | 来源:发表于2018-09-13 21:52 被阅读0次

    在第六篇文章中我说有个问题,其实就是变量的生存周期问题,看如下代码:

    #include <iostream>
    #include <functional>
    
    template<typename T>
    class add {
       public:
          auto operator()(T n, T m) {
             std::cout << "n = " << n << std::endl;
             std::cout << "m = " << m << std::endl;
             return n + m;
          }
    };
    
    auto func(int n) {
       return std::bind(add<int>(), n, std::placeholders::_1);
    }
    
    int main() {
       auto f = func(5);
       std::cout << f(10) << std::endl;
       std::cout << f(200) << std::endl;
       return 0;
    }
    

    我在使用 std::bind 的时候内部申请了一个临时的对象 add<int>(),我的问题是为什么这个对象在函数func return以后没有被回收掉?这个违背了我对栈空间的理解了。我不清楚是编译器坐了优化了,还是C++特有的这个特性?

    昨天测试了一段代码,也有类似的问题:

    
    #include <iostream>
    
    class A {
       public:
          A() {
             std::cout << "constructor A" << std::endl;
          }
          ~A() {
             std::cout << "destructor A" << std::endl;
          }
    };
    
    A func () {
       A a;
    
       return a;
    }
    
    int main() {
       auto a = func();
    
       std::cout << "flag 1" << std::endl;
    
       return 0;
    }
    

    这段代码的输出是什么?我想象中的结果应该会有一次构造函数调用,两次析构函数的调用。然后我又调整了代码如下:

    #include <iostream>
    
    class A {
       public:
          A() {
             std::cout << "constructor A" << std::endl;
          }
    
          A(const A &other) {
             std::cout << "copy constructor A" << std::endl;
          }
    
          ~A() {
             std::cout << "destructor A" << std::endl;
          }
    };
    
    A func() {
       A a;
    
       return a;
    }
    
    int main() {
       auto a = func();
    
       std::cout << "flag 1" << std::endl;
    
       return 0;
    }
    

    这次至少也要输出一个 拷贝构造函数啊,但是也没有,两次代码的输出结果如下:

    constructor A
    flag 1
    destructor A
    

    对于这样的输出我迷惑了,我想是不是我以前的理解都是错的?我不信我又修改了一下:

    #include <iostream>
    
    class A {
       public:
          A() {
             std::cout << "constructor A" << std::endl;
             n = nullptr;
          }
    
          A(const A &other) {
             std::cout << "copy constructor A" << std::endl;
             n = new int(100);
    
          }
    
          ~A() {
             if (n == nullptr) {
                std::cout << "n is nullptr" << std::endl;
             } else {
                std::cout << "n is %d" << *n << std::endl;
                delete n;
             }
             std::cout << "destructor A" << std::endl;
          }
    
       private:
          int * n;
    };
    
    A func() {
       A a;
    
       return a;
    }
    
    int main() {
       auto a = func();
    
       std::cout << "flag 1" << std::endl;
    
       return 0;
    }
    

    结果就是个悲剧,结果如下:

    constructor A
    flag 1
    n is nullptr
    destructor A
    

    我做了最后一次尝试,代码如下:

    #include <iostream>
    
    class A {
       public:
          A() {
             std::cout << "constructor A" << std::endl;
             n = nullptr;
          }
    
          A(A &other) {
             std::cout << "copy constructor A" << std::endl;
             n = new int(100);
    
          }
    
          ~A() {
             if (n == nullptr) {
                std::cout << "n is nullptr" << std::endl;
             } else {
                std::cout << "n is %d" << *n << std::endl;
                delete n;
             }
             std::cout << "destructor A" << std::endl;
          }
    
       private:
          int * n;
    };
    
    A func() {
       A a;
    
       return a;
    }
    
    int main() {
       auto a = func();
    
       std::cout << "flag 1" << std::endl;
    
       return 0;
    }
    

    哈哈,编译不过!!!从这里我明白了一点东西了,编译器的确做了一些优化,不过这种优化更改了原有的语义,就像我们之前演示的那样,总是不能得到想要的结果!这个吗,我觉得无可厚非,为了追求性能,这么也不过分。

    相关文章

      网友评论

          本文标题:C++ 11 新特性(八)

          本文链接:https://www.haomeiwen.com/subject/prwggftx.html