การสร้างเนมสเปซ C ++ ในส่วนหัวและแหล่งที่มา (cpp)


91

มีความแตกต่างระหว่างการตัดทั้งเนื้อหาส่วนหัวและไฟล์ cpp ในเนมสเปซหรือการตัดเฉพาะเนื้อหาส่วนหัวแล้วใช้เนมสเปซในไฟล์ cpp หรือไม่

โดยความแตกต่างฉันหมายถึงโทษประสิทธิภาพการจัดเรียงหรือความหมายที่แตกต่างกันเล็กน้อยที่อาจทำให้เกิดปัญหาหรืออะไรก็ตามที่ฉันต้องระวัง

ตัวอย่าง:

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

หากไม่มีความแตกต่างรูปแบบที่ต้องการคืออะไรและเพราะเหตุใด

คำตอบ:


38

เนมสเปซเป็นเพียงวิธีหนึ่งในการทำลายลายเซ็นฟังก์ชันเพื่อไม่ให้ขัดแย้งกัน บางคนชอบวิธีแรกและอื่น ๆ ชอบเวอร์ชันที่สอง ทั้งสองเวอร์ชันไม่มีผลต่อประสิทธิภาพของเวลาคอมไพล์ โปรดทราบว่าเนมสเปซเป็นเพียงเอนทิตีเวลาคอมไพล์

ปัญหาเดียวที่เกิดขึ้นกับการใช้ namespace คือเมื่อเรามีชื่อ namespace ซ้อนกันเหมือนกัน X::X::Foo(IE) การทำเช่นนั้นทำให้เกิดความสับสนมากขึ้นโดยใช้หรือไม่ใช้คีย์เวิร์ด


56

ความแตกต่างของ "เนมสเปซ X" ถึง "การใช้เนมสเปซ X" คือข้อแรกที่การประกาศใหม่ใด ๆ จะอยู่ภายใต้ช่องว่างของชื่อในขณะที่อันที่สองจะไม่

ในตัวอย่างของคุณไม่มีการประกาศใหม่ดังนั้นจึงไม่มีความแตกต่างดังนั้นจึงไม่มีวิธีที่ต้องการ


ขึ้นอยู่กับโครงการและรูปแบบ บ่อยครั้งที่มีหนึ่งเนมสเปซหลักสำหรับการโหลดไฟล์ในโมดูลและสไตล์ที่สองก็สมเหตุสมผลดี
Nicholas Wilson

8

ไม่มีบทลงโทษด้านประสิทธิภาพเนื่องจากผลลัพธ์อาจเหมือนกัน แต่การใส่Fooเนมสเปซของคุณโดยปริยายจะทำให้เกิดความคลุมเครือในกรณีที่คุณมีFooเนมสเปซที่แตกต่างกัน คุณจะได้รับรหัสของคุณ fubar แน่นอน ฉันขอแนะนำให้หลีกเลี่ยงการใช้usingเพื่อจุดประสงค์นี้

และคุณมีหลง{หลังจากusing namespace;-)


ฉันจะไม่เรียกมันว่าหลงทางเพราะมันตรงกับการปิด}ท้ายสุด อย่างไรก็ตามฉันจะเรียกว่าการจัดฟันคู่นั้นซ้ำซ้อน;)
blubberdiblub

@blubberdiblub คำถามได้รับการแก้ไขแล้วหากคุณตรวจสอบเวอร์ชันดั้งเดิมคุณจะเรียกมันว่าหลงทาง ;-)
Michael Krelin - แฮ็กเกอร์

1

ถ้าอันที่สองรวบรวมเหมือนกันก็ไม่ควรมีความแตกต่าง เนมสเปซถูกประมวลผลในเวลาคอมไพล์และไม่ควรส่งผลต่อการดำเนินการรันไทม์

แต่สำหรับปัญหาการออกแบบประการที่สองน่ากลัว แม้ว่าจะคอมไพล์ (ไม่แน่ใจ) แต่ก็ไม่สมเหตุสมผลเลย


1
ฉันไม่คิดว่ามันรวบรวม แต่ไม่ใช่เพราะมีความแตกต่าง แต่เป็นเพราะมีคนหลงทาง{;-)
Michael Krelin - แฮ็กเกอร์

ความแตกต่างคือ Foo :: TheFunc () ถูกประกาศในเนมสเปซส่วนกลางในขณะที่กำหนดไว้ในเนมสเปซ X
เบิร์ต - ม.ค.

1

Foo :: TheFunc () ไม่ได้อยู่ในเนมสเปซที่ถูกต้องใน VS-case ใช้ 'void X :: Foo :: TheFunc () {}' เพื่อใช้ฟังก์ชันในเนมสเปซที่ถูกต้อง (X)


คำถามเก่าไปหน่อย แต่คุณรู้หรือไม่ว่าผลที่ตามมาคืออะไร? กล่าวคือคุณจะประสบปัญหาใด ๆ กับวิธีที่ VS case ของเขาประกาศฟังก์ชันในเนมสเปซ แต่กำหนดไว้นอกมัน?
Adam Goodwin

1

ในกรณีที่คุณตัดเฉพาะเนื้อหา. h ที่คุณต้องเขียนโดยใช้เนมสเปซ ... ในไฟล์ cpp ไม่เช่นนั้นคุณทุกครั้งที่ทำงานกับเนมสเปซที่ถูกต้อง โดยปกติคุณจะตัดทั้งไฟล์. cpp และ. h ไม่เช่นนั้นคุณมีความเสี่ยงที่จะใช้วัตถุจากเนมสเปซอื่นซึ่งอาจสร้างปัญหาได้มากมาย


0

ฉันคิดว่าสิ่งที่ถูกต้องที่จะทำที่นี่คือการใช้เนมสเปซในการกำหนดขอบเขต

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

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

0

หากคุณกำลังพยายามใช้ตัวแปรจากตัวแปรหนึ่งไปยังอีกตัวแปรหนึ่งฉันขอแนะนำให้กำหนดภายนอกจากนั้นเริ่มต้นในไฟล์ต้นฉบับดังนี้:

// [.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;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.