C++ 11 delete

  • C++11 delete

    • 简介

      • delete声明的函数也会参与匹配,但是编译阶段就明确此类型的函数已被删除.

      • delete的错误可以在编译阶段发现.

    • 回顾C++98

      • 声明为private且不定义. 链接 阶段才能发现.

  • delete解决的问题

    • C++编译器

      • 默认为类创建: 无参构造,析构,拷贝,赋值四个函数.

      • 冲突的就是: 拷贝赋值这两个函数.

    • c++98

      • 通过private私有声明并不定义以此达到目的.但是只能链接阶段才能检测到错误.
      • 代码是先编译,再链接,而链接是最后一步,最后一步才发现可能会过很久,特别是大型的项目编译.

    • c++11

      • C++98的手段在C++11中被加强错误识别时间,编译阶段就可以识别出来.

      • 所以建议采用C++11而不是C++98.

    • 隐式转换

      • 类型之间的隐式转换也会导致不匹配的类型转换调用。
      • 可以通过声明一个对应类型的声明,然后标记为delete就可以规避.
      • 不过之类比较麻烦.

    • 隐式案例

      void cool(int) {}
      void cool(bool) = delete;
      
      int main() {
         cool(1);
         cool(false);
      }
      
      • 后面的会失败.

      • 两种版本的编译

      [root@localhost test]# g++ -c test.cpp -std=c++98
      [root@localhost test]# gcc test.o
      test.o: In function `main':
      test.cpp:(.text+0x1d): undefined reference to `cool(bool)'
      collect2: error: ld returned 1 exit status
      [root@localhost test]# cat test.cpp
      void cool(int) {}
      void cool(bool);
      
      int main() {
         cool(1);
         cool(false);
      }
      [root@localhost test]# vim test.cpp
      [root@localhost test]# g++ -c test.cpp -std=c++11
      test.cpp: In function ‘int main()’:
      test.cpp:6:15: error: use of deleted function ‘void cool(bool)’
          cool(false);
                    ^
      test.cpp:2:6: error: declared here
      void cool(bool) = delete;
           ^
      [root@localhost test]# cat test.cpp
      void cool(int) {}
      void cool(bool) = delete;
      
      int main() {
         cool(1);
         cool(false);
      }
      
      
      • 编译阶段发现错误.

  • 差异

    • C++11

      • public中声明函数,并标记为delete.

      • private则会先检测权限再检测是否delete,得到错误信息.

    • C++98

      • 私有不定义,在链接阶段才能发现问题. 太迟了.

      • 私有拷贝或者赋值对于友元或者成员中可能用到. 仍然只能在链接阶段才发现.

  • delete的强大

    • 强大之处

      • 什么函数都可以delete. 普通函数,模板,类等等,几乎所有.

    • 全局函数delete

      void cool(int) {}
      void cool(bool) = delete;
      
      int main() {
         cool(1);
         cool(false);
      }
      
      • 这里的案例不严谨,可能还有const,volatile之类的修饰会影响,但这里仅仅是个案例.

    • 禁止模板实例化

      template <typename T>
      void show(T a) {}
      
      template<>
      void show<bool>(bool) = delete;
      int main() {
         show(1);
         show(false);
      }
      
      • show(bool)不能被实例化.

      • 这里的案例也不是很完善,虽然也可能是const,volatile之类的.

    • 类成员

      
      class T {
      public:
      template <typename T>
      void show(T a) {}
      template<>
      void show<bool>(bool) = delete;
      };
      
      int main() {
         T a;
         a.show(1);
         a.show(false);
      }
      
      • 编译报错,编译器不允许在类中特例化.

      • 只能在全局或者命名空间里面.

    • C++11标准版

      
      class T {
      public:
      template <typename T>
      void show(T a) {}
      };
      template<>
      void T::show<bool>(bool) = delete;
      
      int main() {
         T a;
         a.show(1);
         a.show(false);
      }
      
      • 还是报错,不允许bool类型的特例化.

  • 总结

    • C++98private声明不定义是可以,但是链接阶段才能发现.

    • C++11publicdelete则在编译阶段即可.

    • delete支持禁止普通函数,模板函数,的实例化.更加强大.

  • 發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章