[c++] 為什麼使用未命名的命名空間以及它們的好處是什麼?



2 Answers

在匿名命名空間中有東西意味著它在本地翻譯單元 (.cpp文件及其所有內容),這意味著如果另一個具有相同名稱的符號在別處定義,則不會違反一個定義規則 (ODR)。

這與具有靜態全局變量或靜態函數的C方式相同,但它也可以用於類定義(在C ++中應該使用而不是static )。

同一文件中的所有匿名命名空間都被視為相同的命名空間,並且不同文件中的所有匿名命名空間都是不同的。 匿名命名空間相當於:

namespace __unique_compiler_generated_identifer0x42 {
    ...
}
using namespace __unique_compiler_generated_identifer0x42;
Question

我剛剛加入了一個新的C ++軟件項目,並試圖理解這個設計。 該項目經常使用未命名的名稱空間。 例如,類定義文件中可能會出現類似這樣的情況:

// newusertype.cc
namespace {
  const int SIZE_OF_ARRAY_X;
  const int SIZE_OF_ARRAY_Y;
  bool getState(userType*,otherUserType*);
}

newusertype::newusertype(...) {...

什麼是可能導致使用未命名名稱空間的設計注意事項? 有什麼優點和缺點?




除了這個問題的其他答案之外,使用匿名命名空間還可以提高性能。 由於命名空間內的符號不需要任何外部鏈接,因此編譯器可以更自由地在名稱空間內對代碼執行主動優化。 例如,一個循環中多次調用的函數可以內聯,而不會對代碼大小產生任何影響。

例如,在我的系統中,如果使用匿名名稱空間(x86-64 gcc-4.6.3和-O2;注意add_val中的額外代碼使編譯器不想包含它兩次)。

#include <iostream>

namespace {
  double a;
  void b(double x)
  {
    a -= x;
  }
  void add_val(double x)
  {
    a += x;
    if(x==0.01) b(0);
    if(x==0.02) b(0.6);
    if(x==0.03) b(-0.1);
    if(x==0.04) b(0.4);
  }
}

int main()
{
  a = 0;
  for(int i=0; i<1000000000; ++i)
    {
      add_val(i*1e-10);
    }
  std::cout << a << '\n';
  return 0;
}



未命名的命名空間將類,變量,函數和對象的訪問權限限制在其定義的文件中。 未命名的命名空間功能類似於C / C ++中的static關鍵字。
static關鍵字將全局變量和函數的訪問權限限制在定義它們的文件中。
未命名的命名空間和static關鍵字之間存在差異,因為其中的未命名的命名空間比靜態有優勢。 static關鍵字可以與變量,函數和對像一起使用,但不能與用戶定義的類一起使用。
例如:

static int x;  // Correct 

但,

static class xyz {/*Body of class*/} //Wrong
static structure {/*Body of structure*/} //Wrong

但是對於未命名的命名空間也是一樣的。 例如,

 namespace {
           class xyz {/*Body of class*/}
           static structure {/*Body of structure*/}
  } //Correct



Related