Namespace trong C++

Xét một tình huống, khi chúng ta có hai người cùng tên là Zara, trong cùng lớp. Bất cứ khi nào cần phân biệt họ một cách rõ ràng, chúng ta sẽ phải sử dụng thông tin bổ sung cùng với tên của họ, ví dụ: vị trí họ sống hay tên cha mẹ của họ...

Tình huống tương tự xảy ra trong C++. Ví dụ: Code bạn đang viết có hàm tên là xyz() và có thư viện khác có sẵn mà cũng có hàm xyz(). Bây giờ, trình biên dịch không biết phiên bản nào của hàm xyz() mà bạn muốn sử dụng trong code của mình.

Một namespace trong C++ giúp bạn giải quyết tình huống này và được sử dụng như là thông tin bổ sung để phân biệt các hàm, lớp, biến… cùng tên có sẵn trong các thư viện khác nhau. Sử dụng namespace trong C++, bạn có thể định nghĩa bối cảnh trong đó các tên được định nghĩa. Về bản chất, một namespace định nghĩa một phạm vi trong C++.

Định nghĩa một Namespace trong C++

Một định nghĩa namespace bắt đầu với từ khóa namespace, đi sau là tên của namespace đó, như sau:

namespace ten_cua_namespace {
    // phần khai báo code
 }

Để gọi phiên bản namespace của hàm hoặc biến, bạn thêm (::) vào sau tên của namespace, như sau:

name::code;  // code có thể là một biến hoặc hàm.

Ví dụ sau minh họa cách namespace định nghĩa phạm vi của biến và hàm trong C++:

#include <iostream>
 using namespace std;
 
 // Đây là namespace dau_tien
 namespace dau_tien{
    void ham(){
       cout << "Bên trong namespace dau_tien" << endl;
    }
 }
 // Đây là namespace thu_hai
 namespace thu_hai{
    void ham(){
       cout << "Bên trong namespace thu_hai" << endl;
    }
 }
 int main ()
 {
  
    // Gọi hàm từ namespace dau_tien.
    dau_tien::ham();
    
    // Gọi hàm từ namespace thu_hai.
    thu_hai::ham(); 
 
    return 0;
 }

Biên dịch và chạy chương trình C++ trên sẽ cho kết quả sau:

Bên trong namespace dau_tien
 Bên trong namespace thu_hai

Chỉ thị using namespace trong C++

Bạn có thể tránh việc phụ thêm vào sau tên của namespace bằng việc sử dụng chỉ thị using namespace directive trong C++. Chỉ thị này nói cho compiler rằng dãy code ở sau đang sử dụng các tên trong namespace đã xác định đó. Bạn xét ví dụ:

#include <iostream>
 using namespace std;
 
 // Đây là namespace dau_tien
 namespace dau_tien{
    void ham(){
       cout << "Bên trong namespace dau_tien" << endl;
    }
 }
 // Đây là namespace thu_hai
 namespace thu_hai{
    void ham(){
       cout << "Bên trong namespace thu_hai" << endl;
    }
 }
 using namespace dau_tien;
 int main ()
 {
  
    // Gọi hàm từ namespace dau_tien.
    ham();
    
    return 0;
 }

Biên dịch và thực thi code trên sẽ cho kết quả:

Bên trong namespace dau_tien

using namespace directive trong C++ cũng có thể được sử dụng để tham chiếu một item cụ thể trong một namespace. Ví dụ, nếu bạn chỉ có ý định sử dụng một phần cout của std namespace, bạn có thể tham chiếu nó như sau:

using std::cout;

Phần code theo sau có thể tham chiếu tới cout mà không cần phụ thêm vào sau namespace, nhưng các item khác trong std namespace vẫn cần phải rõ ràng, như sau:

#include <iostream>
 using std::cout;
 
 int main ()
 {
    cout << "std::endl duoc su dung voi std!" << std::endl;
    
    return 0;
 }

Biên dịch và chạy chương trình C++ trên sẽ cho kết quả sau:

std::endl duoc su dung voi std!

Các tên được giới thiệu trong một using namespace directive tuân theo các qui tắc phạm vi (scope rule). Tên là nhìn thấy bắt đầu từ vị trí của using namespace directive tới phần cuối của phạm vi mà trong đó directive này được thấy. Các thực thể với cùng tên được định nghĩa trong phạm vi bên ngoài bị ẩn.

Namespace không kề nhau trong C++

Một namespace có thể được định nghĩa thành một số phần và vì thế một namespace được tạo từ một tập hợp các phần được định nghĩa riêng biệt. Các phần riêng biệt này của một namespace có thể ở nhiều file khác nhau.

Vì thế, nếu một phần của namespace đó yêu cầu một tên được định nghĩa ở file khác, thì tên đó vẫn phải được khai báo. Định nghĩa namespace sau hoặc định nghĩa một namespace mới hoặc thêm các phần tử mới tới namespace đã tồn tại:

namespace ten_cua_namespace {
    // phan khai bao cac code
 }

Namespace lồng nhau trong C++

Trong C++, namespace có thể lồng vào nhau, tức là bạn có thể định nghĩa một namespace bên trong một namespace khác, như sau:

namespace namespace_dau_tien {
    // phan khai bao cac code
    namespace namespace_thu_hai {
       // phan khai bao cac code
    }
 }

Bạn có thể truy cập các thành viên của namespace lồng nhau này bởi sử dụng toán tử phân giải phạm vi (resolution operator) trong C++, như sau:

// de truy cap cac thanh vien cua namespace thu hai
 using namespace namespace_dau_tien::namespace_thu_hai;
 
 // de truy cap cac thanh vien cua namespace dau tien
 using namespace namespace_dau_tien;

Trong các lệnh trên, nếu bạn đang sử dụng namespace_dau_tien, thì nó sẽ làm cho các phần tử của namespace_thu_hai có sẵn trong phạm vi đó, như sau:

#include <iostream>
 using namespace std;
 
 // day la namespace dau tien
 namespace dau_tien{
    void ham(){
       cout << "Ben trong namespace dau_tien" << endl;
    }
    // day la namespace thu hai
    namespace thu_hai{
       void ham(){
          cout << "Ben trong namespace thu_hai" << endl;
       }
    }
 }
 using namespace dau_tien::thu_hai;
 int main ()
 {
  
    // goi ham tu namespace thu hai.
    ham();
    
    return 0;
 }

Biên dịch và chạy chương trình C++ trên sẽ cho kết quả sau:

Ben trong namespace thu_hai

Theo Tutorialspoint

Bài trước: Bộ nhớ động trong C++

Bài tiếp: Template trong C++

Thứ Ba, 09/10/2018 14:31
51 👨 399