Başlıkta ve kaynakta (cpp) C ++ ad alanı oluşturma


90

Bir ad alanında hem başlık hem de cpp dosya içeriklerini sarmalamak veya yalnızca başlık içeriğini sarmak ve ardından cpp dosyasında ad alanını kullanmak arasında herhangi bir fark var mı ?

Fark derken, sorunlara veya bilmem gereken herhangi bir şeye neden olabilecek herhangi bir performans cezası veya biraz farklı anlambilim kastediyorum.

Misal:

// header
namespace X
{
  class Foo
  {
  public:
    void TheFunc();
  };
}

// cpp
namespace X
{
  void Foo::TheFunc()
  {
    return;
  }
}

VS

// header
namespace X
{
  class Foo
  {
  public:
    void TheFunc();
  };
}

// cpp
using namespace X;
{
  void Foo::TheFunc()
  {
    return;
  }
} 

Fark yoksa tercih edilen form nedir ve neden?

Yanıtlar:


38

Ad alanı, işlev imzasını birbiriyle çakışmayacak şekilde karıştırmanın bir yoludur. Bazıları birinci yolu tercih ederken, diğerleri ikinci versiyonu tercih eder. Her iki sürümün de derleme zamanı performansı üzerinde herhangi bir etkisi yoktur. İsim alanlarının sadece bir derleme zamanı varlığı olduğuna dikkat edin.

Ad alanı kullanımıyla ortaya çıkan tek sorun, aynı iç içe geçmiş ad alanı adlarına (yani) sahip olduğumuz zamandır X::X::Foo. Bunu yapmak, anahtar kelime kullanarak veya kullanmadan daha fazla kafa karışıklığı yaratır.


56

"X ad alanı" ile "X ad alanını kullanma" arasındaki fark, ilkinde herhangi bir yeni bildirim ad alanının altında olacak, ikincisinde olmayacak olmasıdır.

Örneğinizde yeni bir beyan yoktur - dolayısıyla hiçbir fark yoktur, dolayısıyla tercih edilen bir yol yoktur.


Projeye ve stile göre değişir. Çoğunlukla bir modüldeki dosya yükü için bir ana ad alanı vardır ve ikinci stil anlamlıdır.
Nicholas Wilson

8

Ortaya çıkan sonuç aynı olabileceğinden, performans cezası yoktur, ancak farklı ad alanlarında Foos'lerinizin olması durumunda sizi ad alanına koymak örtük olarak belirsizlik getirir Foo. Kod fubar'ınızı gerçekten alabilirsiniz. usingBu amaçla kullanmaktan kaçınmanızı tavsiye ederim .

Ve {sonra using namespace;-)


}En sondaki kapanışla eşleştiği için ona başıboş demezdim . Ancak, bu çift diş
teline

orijinal halini kontrol eğer @blubberdiblub, soru düzenlendiği, sen olur o ;-) başıboş çağrı
korsanı - Michael Krelin

1

İkincisi de derlenirse, hiçbir farklılık olmamalıdır. Ad alanları derleme zamanında işlenir ve çalışma zamanı eylemlerini etkilememelidir.

Ancak tasarım sorunları için ikincisi korkunç. Derlese bile (emin değil), hiç mantıklı değil.



Aradaki fark Foo :: TheFunc (), global ad alanında bildirilirken, X ad alanında tanımlanır.
bert-jan

1

Foo :: TheFunc (), VS durumunda doğru ad alanında değil. İşlevi doğru ad alanında (X) uygulamak için 'void X :: Foo :: TheFunc () {}' kullanın.


Soru biraz eski, ama bunun sonuçlarının ne olduğunu biliyor musunuz? Yani, VS durumunun ad alanındaki işlevleri bildirme, ancak bunların dışında bunları tanımlama biçiminde herhangi bir sorunla karşılaşır mısınız?
Adam Goodwin

1

Eğer sadece .h içeriğini kaydırırsanız, cpp dosyasında ... ad alanını kullanarak yazmanız gerekir, aksi takdirde her seferinde geçerli ad alanı üzerinde çalışırsınız. Normalde hem .cpp hem de .h dosyalarını sararsınız, aksi takdirde çok fazla sorun oluşturabilecek başka bir ad alanındaki nesneleri kullanma riskiniz vardır.


0

Bence burada yapılacak doğru şey, kapsam belirleme için ad alanını kullanmaktır.

namespace catagory
{
    enum status
    {
      none,
      active,
      paused
    }
};

void func()
{
    catagory::status status;
    status = category::active;
}

0

Değişkenleri birinden diğerine kullanmaya çalışıyorsanız, onları dışsallaştırmanızı ve ardından kaynak dosyada şu şekilde başlatmanızı öneririm:

// [.hh]
namespace example
{
   extern int a, b, c;
}
// [.cc]
// Include your header, then init the vars:
namespace example
{
   int a, b, c;
}
// Then in the function below, you can init them as what you want: 
void reference
{
    example::a = 0;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.