Membuat namespace C ++ di header dan source (cpp)

90

Apakah ada perbedaan antara membungkus konten file header dan cpp dalam namespace atau hanya membungkus konten header dan kemudian melakukan penggunaan namespace di file cpp?

Yang saya maksud dengan perbedaan adalah hukuman kinerja apa pun atau semantik yang sedikit berbeda yang dapat menyebabkan masalah atau apa pun yang perlu saya waspadai.

Contoh:

// 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;
  }
} 

Jika tidak ada perbedaan apa bentuk yang disukai dan mengapa?

tautan77
sumber

Jawaban:

38

Namespace hanyalah cara untuk mengatur fungsi tanda tangan agar tidak terjadi konflik. Beberapa lebih suka cara pertama dan yang lain lebih suka versi kedua. Kedua versi tersebut tidak berpengaruh pada kinerja waktu kompilasi. Perhatikan bahwa ruang nama hanyalah entitas waktu kompilasi.

Satu-satunya masalah yang muncul dengan menggunakan namespace adalah ketika kita memiliki nama namespace bertingkat yang sama (yaitu) X::X::Foo. Melakukan hal itu akan menimbulkan lebih banyak kebingungan dengan atau tanpa menggunakan kata kunci.

vprajan.dll
sumber
56

Perbedaan antara "namespace X" dengan "menggunakan namespace X" ada di yang pertama, setiap deklarasi baru akan berada di bawah ruang nama sedangkan di deklarasi kedua tidak.

Dalam contoh Anda tidak ada pernyataan baru - jadi tidak ada perbedaan maka tidak ada cara yang disukai.

Roee Gavirel
sumber
Itu tergantung pada proyek dan gaya. Seringkali ada satu namespace utama untuk memuat file dalam modul, dan gaya kedua masuk akal.
Nicholas Wilson
8

Tidak ada penalti performa, karena hasilnya bisa saja sama, tetapi memasukkan Anda Fooke dalam namespace secara implisit menimbulkan ambiguitas jika Anda memiliki Foos di namespace yang berbeda. Anda memang bisa mendapatkan kode fubar Anda. Saya akan merekomendasikan menghindari penggunaan usinguntuk tujuan ini.

Dan Anda tersesat {setelah using namespace;-)

Michael Krelin - peretas
sumber
Saya tidak akan menyebutnya tersesat, karena cocok dengan penutupan }di bagian paling akhir. Namun, saya akan menyebut sepasang kawat gigi itu berlebihan;)
blubberdiblub
@blubberdiblub, pertanyaannya telah diedit, jika Anda memeriksa versi aslinya, Anda akan menyebutnya stray ;-)
Michael Krelin - hacker
1

Jika yang kedua dikompilasi juga, seharusnya tidak ada perbedaan. Namespaces diproses dalam waktu kompilasi dan tidak boleh memengaruhi tindakan waktu proses.

Tapi untuk masalah desain, yang kedua sangat buruk. Bahkan jika dikompilasi (tidak yakin), itu tidak masuk akal sama sekali.

holgac
sumber
1
Saya tidak berpikir itu dapat dikompilasi, tetapi bukan karena ada perbedaan, tetapi karena ada yang tersesat {;-)
Michael Krelin - peretas
Perbedaannya adalah Foo :: TheFunc () dideklarasikan di namespace global, sementara itu ditentukan di namespace X.
bert-jan
1

Foo :: TheFunc () tidak berada dalam namespace yang benar dalam kasus VS. Gunakan 'void X :: Foo :: TheFunc () {}' untuk mengimplementasikan fungsi dalam namespace (X) yang benar.

bert-jan
sumber
Pertanyaannya agak lama, tetapi apakah Anda tahu apa akibatnya? yaitu apakah Anda akan mengalami masalah dengan cara kasus VS-nya mendeklarasikan fungsi dalam namespace, tetapi mendefinisikannya di luar namespace?
Adam Goodwin
1

Jika Anda hanya membungkus konten .h Anda harus menulis menggunakan namespace ... di file cpp jika tidak, Anda setiap kali bekerja di namespace yang valid. Biasanya Anda membungkus kedua file .cpp dan .h jika tidak, Anda berisiko menggunakan objek dari namespace lain yang dapat menimbulkan banyak masalah.

AlexTheo
sumber
0

Saya pikir hal yang benar untuk dilakukan di sini adalah menggunakan namespace untuk pelingkupan.

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

void func()
{
    catagory::status status;
    status = category::active;
}
Kjetil Hvalstrand
sumber
0

Jika Anda mencoba menggunakan variabel dari satu variabel ke variabel lainnya, saya sarankan untuk mengeksternalisasi variabel tersebut, kemudian menginisialisasi variabel tersebut di file sumber seperti:

// [.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;
}

sumber