我愛學習網-上傳
當前位置: 主頁 > 文庫 > C++ >

C++ 函數刪除聲明

時間:2020-10-30 16:34來源:我愛學習網 作者:apple 點擊:

不可拷貝類的設計

我們知道有些對象 (比如文件流) 的拷貝與移動是沒有意義的,那我們應該怎樣禁止該類對象的拷貝和移動操作呢?有兩種途徑:

  1. 私有化聲明拷貝和移動類成員函數
  2. 公開化刪除拷貝和移動類成員函數 (C++11)

代碼示例 :

#include 

class Noncopyable {
protected:
#if __cplusplus >= 201103L
  Noncopyable() = default;
  ~Noncopyable() = default;
#else
  Noncopyable() {}
  ~Noncopyable() {}
#endif

#if __cplusplus >= 201103L
  Noncopyable(const Noncopyable &) = delete;
  Noncopyable &operator=(const Noncopyable &) = delete;
#else
private:
  Noncopyable(const Noncopyable &);
  Noncopyable &operator=(const Noncopyable &);
#endif
};

class Job : Noncopyable {};

int main(void) {
  Job j11 = Job{}; // works, C++17 copy elision

  // Job j21 = j11; // calls to delete copy ctor, error compile
  Job j22;
  // j22 = Job{};   // calls to delete copy assignment, error compile

  return 0;
}

公開化刪除拷貝和移動類成員函數:可以直接放到 public 域下更好的展現出來,并且編譯錯誤信息友好

私有化聲明拷貝和移動類成員函數:只有聲明沒有定義,編譯錯誤會延遲到鏈接階段,并且提示信息不友好

 

這里的 Noncopyable 基類修改自 Boost 庫的 noncopyable 類,protected 的使用,使其只能作為基類使用

普通函數刪除

已經公開了的函數,別人可能在使用,冒然刪除,不夠友好,實際上我們可以先給出廢棄警告,給別人一些緩沖時間來做修改,然后在一個未來的版本中徹底刪除。

代碼示例 :

// deletefn.cpp
#include 

// deprecated a function
[[deprecated("use GoodLuckyExt instead")]] void GoodLucky() {
  std::cout << "GoodLucky\n";
}
void GoodLuckyExt() { std::cout << "GoodLuckyExt\n"; }

// char, bool, double can implicitly convert to int
// delete functions
bool isLucky(int) { return true; }; // original function
bool isLucky(char) = delete;        // reject chars
bool isLucky(bool) = delete;        // reject bools
bool isLucky(double) = delete;      // reject doubles and floats

int main(void) {
  // deprecated warning
  GoodLucky();

  // function deleted
  isLucky(2); // works
  // isLucky(2.0);  // not compiles, calls to delete function
  // isLucky(true); // not compiles, calls to delete function

  return 0;
}

$ clang++ deletefn.cpp -std=c++17

deletefn.cpp:19:3: warning: 'GoodLucky' is deprecated: use GoodLuckyExt instead [-Wdeprecated-declarations]

模板函數刪除

模板函數的刪除和普通函數的刪除類似,實際上就是刪除一些特化,偏特化的函數版本,這個技術也比較有用,能減少模板函數的實例化數量。

代碼示例 :

#include 

// function template
template  void processPointer(T *ptr) { std::cout << ptr << '\n'; }
// delete specialized instantiations
template <> void processPointer(void *ptr) = delete;
template <> void processPointer(char *ptr) = delete;

// function template in class
struct Job {
  template  void processPointer(T *ptr) { std::cout << ptr << '\n'; }
};

// delete specialized instantiations outside of class, still as public
template <> void Job::processPointer(void *ptr) = delete;
template <> void Job::processPointer(char *ptr) = delete;

int main(void) {
  int i{0};
  char c{'c'};
  processPointer(&i); // 0x7ffee8be4c08
  // processPointer(&c); // call to delete function

  Job j;
  j.processPointer(&i); // 0x7ffee8be4c08
  // j.processPointer(&c); // call to delete member function

  return 0;
}

私有化對類的模板成員函數無能為力,只能在類外使用 delete 刪除指定的實例化版本

總結

  1. delete 能刪除類的特殊成員函數,也能刪除類的模板成員函數
  2. delete 能刪除自由函數,也能刪除自由模板函數
  3. 刪除一個公開的函數之前,可以給出廢棄警告,得益于現代 C++ 的 [[deprecated]] 屬性
------分隔線----------------------------
    ?分享到??
看看啦
主站蜘蛛池模板: 亚洲一区二区三区深夜天堂| 久久一区二区精品综合| 精品一区狼人国产在线| 精品一区二区三区在线观看| 内射白浆一区二区在线观看| 在线观看视频一区二区| 亚洲综合一区无码精品| 国产精品免费一区二区三区四区| 国产品无码一区二区三区在线| 国产高清不卡一区二区| 亚洲av无码一区二区三区天堂古代| 国产成人精品无码一区二区老年人| 国产一区二区在线|播放| 亚洲国产一区二区三区| 日韩免费无码一区二区三区 | 国产精品无圣光一区二区| 亚洲综合无码一区二区三区 | 日韩在线不卡免费视频一区| 伊人激情AV一区二区三区| 亚洲国产AV一区二区三区四区| 中文字幕无码不卡一区二区三区| 国产一区二区三区久久| 无码一区二区三区在线观看| 亚洲一区在线免费观看| 亚洲熟妇AV一区二区三区浪潮| 亚洲一区二区三区国产精华液| 国产精品污WWW一区二区三区| 精品国产AV一区二区三区| 久久国产午夜精品一区二区三区| 国模私拍福利一区二区| 亚洲av无码一区二区三区天堂| www.亚洲一区| 在线播放国产一区二区三区 | 乱子伦一区二区三区| 麻豆国产一区二区在线观看| 国产一区二区三区不卡在线观看 | 国产乱码精品一区二区三区四川人| 日本美女一区二区三区| 精品女同一区二区三区免费站| 亚洲第一区精品观看| 亚洲AV网一区二区三区|