4.7. Hành trình không dừng lại

Dù rằng các bạn vẫn chưa thể biết tất cả mọi điều về C++, giáo trình của chúng ta vẫn phải kết thúc tại đây. Ngoài ra, chúng ta cũng cần hiểu là không ai có thể biết mọi thứ về C++ cũng như tất cả các thư viện của nó.

Nhưng giáo trình kết thúc không đồng nghĩa với con đường của các bạn đã dừng lại. Trong thực tế, mục đích của giáo trình này chỉ là cung cấp cho các bạn những nền tảng cơ bản để các bạn có thể tự mình học hỏi các kỹ thuật nâng cao khi cần thiết vì nếu yêu cầu tôi phải dạy các bạn tất cả mọi thứ về C++ thì có chết già cũng không thể hết được. Chưa kể bản thân tôi cũng không biết tất cả mọi thứ !

Mục đích của bài học cuối cùng này là chỉ ra cho các bạn 1 số con đường mà các bạn có thể đi theo khi muốn biết thêm về C++. Cuối cùng, có sử dụng đến chúng không hoàn toàn là quyết định của chính các bạn.

! Các khái niệm trong bài học này chỉ được giới thiệu chứ không được giải thích cặn kẽ như mọi khi. Nó đơn giản là 1 danh sách những điều mới mẻ để giúp định hướng các bạn khi muốn tìm hiểu thêm về ngôn ngữ vào 1 ngày đẹp trời nào đó khi các bạn có thời gian.

Tiến xa hơn với C++

Ngôn ngữ chúng ta đang thảo luận khá phong phú đến nỗi những gì chúng ta đã biết quả thật quá ít khi đem ra so sánh với những gì chúng ta chưa tìm hiểu. Một vài trong số chúng đặc biệt phức tạp và thú thực là không phải lúc nào cũng cần sử dụng đến.

Tuy nhiên, chúng ta vẫn sẽ liệt kê chúng ra đây phòng khi 1 ngày nào đó các bạn lạc hướng và cần bắt đầu tìm hiểu về chúng trước khi nhờ Google giải thích sâu hơn.

Và đây là danh sách các khái niệm mà chúng ta sẽ nhắc đến trong bài này :

  • Đa kế thừa
  • Không gian tên (namespace)
  • Kiểu liệt kê
  • typedef
Đa kế thừa

Đa kế thừa là thuật ngữ nói về việc 1 lớp đồng thời kế thừa nhiều lớp khác nhau. Chúng ta đã từng gặp qua nó khi thực hành với Qt lúc thao tác tạo giao diện người dùng.

Để kế thừa nhiều lớp cùng lúc, chúng ta chỉ cần đơn giản là viết tất cả tên các lớp, ngăn cách bởi dấu ,, muốn kế thừa vào sau dấu :

class CuaSoNguoiDung : public QWidget, private Ui::CuaSoNguoiDung {
}

Nhìn qua thì có vẻ là 1 khái niệm đơn giản. Trong thực tế thì nó lại khá là phức tạp.

Ngày nay, đa phần các ngôn ngữ hiện đại như Java hay Ruby đều không hỗ trợ đa kế thừa. Lý do đơn giản vì lợi ích nó mang lại trong 1 số ít trường hợp không thể đánh đổi được ác mộng mà nó mang đến khi sử dụng không hợp lý.

Nếu muốn, hãy tìm hiểu sơ qua về nó biết rằng nó không phải lúc nào cũng hữu dụng.

Không gian tên (namespace)

 Ngay những ngày đầu tiếp xúc với C++, chúng ta đã mặc sức sử dụng cincout để nhập từ bàn phím và hiển thị thông tin ra màn hình.

Dưới đây vẫn là đoạn mã quen thuộc đó, nhưng với tên thật của các phương thức mà chúng ta đã sử dụng.

#include <iostream>
int main() {
        std::cout << "Xin chao Tan binh!" << std::endl;
        return 0;
}

Tiền tố std:: chính là thứ mà chúng ta gọi là namespace hay không gian tên khi dịch sang tiếng Việt. Các namespace khá hữu dụng trong các chương trình lớn khi chúng ta cần phải sử dụng vô số lớp và biến với đủ loại tên khác nhau.

Khi mã nguồn chương trình trở nên khổng lồ, xác suất 1 cái tên được sử dụng lại là rất lớn. Ví dụ như chúng ta có thể có 2 lớp cùng tên là MauSac trong 2 thư viện khác nhau về giao diện hình ảnh và xử lý mã trò chơi.

Về cơ bản thì việc 2 lớp trùng tên bị cấm trong C++, đương nhiên là trừ khi chúng nằm trong không gian tên khác nhau. Hãy tưởng tượng các không gian tên giống như những chiếc hộp giúp chúng ta không bị nhầm lẫn giữa các tên lớp và biến giống nhau.

Nếu 1 lớp thuộc về 1 không gian tên nào đó thì tên lớp đó phải có thêm tiền tố là tên của không gian chứa nó.

Trochoi3D::MauSac do; //Su dung lop MauSac trong namespace TroChoi3D
CuaSo::MauSac xanh; //Lop khac cung ten la MauSac trong namespace CuaSo.

Các không gian tên cũng giống như tên họ để phân biệt gốc gác của các biến vậy.

Không gian tên « std » được sử dụng cho toàn bộ thư viện chuẩn của C++. Vậy nên đáng ra cần thêm nó vào tất cả những thứ chúng ta sử dụng của thư viện chuẩn như cin, vector, string, vv…

Tuy vậy, chúng ta cũng có thể sử dụng using namespace để tránh phiền toái này.

using namespace std;

Nhờ lệnh này, trong toàn bộ tệp, trình biên dịch sẽ biết là phải tìm các biến và lớp trong không gian tên std. Khá hữu dụng để tránh phải thêm std:: vào khắp nơi.

! 1 số lập trình viên thì lại không thích sử dụng using namespace với lý do khi đọc lại mã, họ muốn ngay lập tức xác định được biến hay lớp đang sử dụng đến từ không gian nào. Nói chung, đây là vấn đề lựa chọn của từng người.

Kiểu liệt kê

Trong 1 chương trình, đôi khi chúng ta cần thao tác với những biến chỉ có thể mang những giá trị nhất định, ví dụ như độ khó của trò chơi chỉ có 3 mức dễ, trung bình và khó. Việc sử dụng kiểu số nguyên với các giá trị 1, 2, 3 là 1 giải pháp nhưng không được an toàn lắm do không thể đảm bảo là 1 biến số nguyên chỉ nhận những giá trị đó. Đây là lúc chúng ta cần tạo ra 1 kiểu dữ liệu mà chỉ có 3 giá trị và đó là kiểu liệt kê.

Kiểu liệt kê được khai báo như sau :

enum MucDoKho{De, TrungBinh, Kho};

Và sử dụng chúng như bất cứ kiểu dữ liệu nào khác.

int main() {
    MucDoKho mucDo;
    //…
    if(mucDo == TrungBinh) {
        cout << "Ban da chon do kho trung binh !" << endl;
    }
    //…
    return 0;
}

Khá hữu dụng và hiển nhiên là rõ ràng hơn là đoạn mã kiểu như if(mucDo == 2) vì người đọc có thể chả biết mức độ 2 có nghĩa là gì.

Chúng ta rất hay gặp kiểu dữ liệu này với các lệnh điều kiện switch. Dưới đây là 1 ví dụ về kiểu dữ liệu biểu diễn phương hướng.

enum Huong{Dong, Tay, Nam, Bac};
int main() {
    Huong phuongHuong;
    NhanVat nhanVat;
    //…
    switch(phuongHuong) {
        case Dong: nhanVat.diChuyenHuongDong(); break;
        case Tay: nhanVat. diChuyenHuongTay(); break;
        case Nam: nhanVat. diChuyenHuongNam(); break;
        case Bac: nhanVat. diChuyenHuongBac(); break;
    }
    //…
    return 0;
}
Khái niệm typedef

Các bạn cảm thấy mã nguồn quá dài ? Sau đây là 1 thao tác giúp chúng ta tiết kiệm 1 số chữ.

Hãy tưởng tượng những kiểu dữ liệu mà tên chúng dài dằng dặc cả cây số, ví dụ như kiểu của các biến đếm. Kinh khủng hơn, chúng ta còn phải viết đi viết là chúng nhiều lần do sử dụng đến nhiều biến khác nhau.

std::map<std::string, std::vector<int> >::iterator it;

Dài nhỉ ! typedef chính là giải pháp chúng ta đang tìm kiếm do nó cho phép chúng định nghĩa 1 biệt danh ngắn hơn cho 1 kiểu dữ liệu bất kỳ. Ví dụ như khi chúng ta muốn đặt biệt danh BienDem cho kiểu dữ liệu được nhắc đến ở trên.

typedef std::map<std::string, std::vector<int> >::iterator BienDem

Và chúng ta có thể khai báo ngắn gọn như sau.

BienDem it;

Đương nhiên là chỉ sử dụng có 1 lần kiểu dữ liệu này thì chúng ta sẽ chẳng tiết kiệm được gì nhiều. Vấn đề là nếu đây là kiểu dữ liệu thường xuyên lặp lại thì chúng ta lai có thể tiết kiệm được kha khá công sức. Khá là hữu dụng trong 1 số trường hợp.

Tiến xa hơn với các thư viện khác

Như những gì chúng ta đã làm với Qt, khi làm việc với C++, chúng ta rất hay sử dụng đến cái chúng ta gọi là thư viện bên thứ 3. Vấn đề là có hàng trăm nếu không muốn nói là hàng nghìn các thư viện tồn tại ngoài kia và sự lựa chọn không phải lúc nào cũng dễ dàng. Chỉ riêng với việc tạo ra cửa sổ, tôi cũng có thể dễ dàng liệt kê ra cả chục thư viện khác nhau. May mắn cho các bạn là tôi đã ở đây làm hướng dẫn viên miễn phí cho chuyến tham quan rừng rậm nguyên thủy này.

Thư viện trò chơi 2D

Allergo là 1 thư viện đa nền tảng chuyên cho thiết kế trò chơi. Những đấng sáng tạo của nó đã tối ưu hóa của thư viện này giúp những trò chơi mà nó tạo ra có thể hoạt động nhanh nhất có thể. Nó quản lý tất cả mọi thứ cần thiết để tạo ra trò chơi như nút bấm, tay cầm, âm thanh, hình ảnh và cả đống thứ khác. Vấn đề duy nhất của nó với chúng ta chỉ có thể là tài liệu của nó hoàn toàn bằng tiếng Anh chứ không phải tiếng Việt. Thế nhưng việc này thì chúng ta quen rồi nhỉ.

SFML (Simple and Fast Multimedia Library) đúng như tên gọi của nó, là 1 thư viện đa phương tiện nhanh và đơn giản. Thư viện này khá dễ sử dụng và cũng cung cấp đủ công cụ cần thiết, dưới dạng các lớp, để tạo ra các trò chơi. 1 ưu điểm nữa của thư viện này là nó được chia nhỏ ra thành các gói độc lập, cho phép người dùng tập trung vào sử dụng những tính năng nhất định mà họ cần như hình ảnh, âm thanh hay quản lý mạng chẳng hạn.

Điểm đặc biệt của thư viện này là là người tạo ra nó sử dụng tiếng Pháp. Điều này khiến nó trở nên dễ dàng để sử dụng hơn với 1 số người và tăng thêm độ khó với những người khác. Cuối cùng thì, sử dụng hay không hoàn toàn là quyền của các bạn.

Làm việc với 3D (3 chiều)

Cần thừa nhận là đây là 1 lĩnh vực rất rộng và hấp dẫn. Ngày này, đa phần các trò chơi được tạo ra dưới dạng 3D và rất nhiều người lựa chọn đi học C++ chỉ đơn giản để có thể tạo ra các trò chơi 3 chiều này.

Về cơ bản, hiện này tồn tại 2 API (giao diện lập trình ứng dụng) được sử dụng để thao tác với các card đồ họa mà các bạn chắc chắn đã từng được nghe nói tới : DirectX và OpenGL. Cái đầu tiên chỉ sử dụng được trên nên Windows.

Với 2 API này, chúng ta có thể thực hiện tất cả mọi thứ. Vấn đề là sức mạnh của chúng đến từ việc chúng chỉ cung cấp các tính năng cơ bản như vẽ hình khối, tạo điểm, vv… Vì vậy để thực hiện 1 phân cảnh mà nhân vật có thể di chuyển với các hiệu ứng đòi hỏi 1 lượng công việc khá lớn. Chính vì lẽ đó, trên thị trường tồn tại những chương trình gọi là « động cơ 3D », cung cấp các tính năng cao cấp hơn và dễ sử dụng hơn. Hầu hết các trò chơi mà chúng ta đang chơi ngày nay được tạo ra nhờ những động cơ này. Đấy mới là bộ công cụ hữu ích mà các lập trình viên hay sử dụng.

Trong số tất cả các động cơ 3D, có 2 loại khá phổ biến và dễ sử dụng mà các bạn có thể thử, đó là Irlicht và Orgre3D.

2 thư viện này cung cấp các lớp và hàm hữu dụng. Như mọi khi, chúng ta cần phải biết tiếng Anh nếu muốn sử dụng tài liệu của những thư viện này.

Để lựa chọn giữa những thư viện này, lời khuyên của tôi là hãy quan sát thử những đoạn mã nguồn ví dụ cũng như phần đầu của bản hướng dẫn cho người mới mà chúng cung cấp rồi các bạn sẽ có thể tự mình chọn ra loại nào thích hợp với mình nhất.

Và giao diện đồ họa nói chung

Trong giáo trình này, chúng ta đã sử dụng Qt, nhưng nên nhớ đây không phải là thư viện duy nhất cho phép làm việc với giao diện đồ họa. Ngược lại, chúng ta có cả đống sự lựa chọn ngoài kia. Ở đây, tôi liệt kê ra 2 thư viện khác cũng được sử dụng khá nhiều trong nhiều dự án khác nhau.

wxWidgets

wxWidgets có nhiều điểm tương đồng với Qt trong cách tạo ra và quản lý các cửa sổ cũng như các widget. Chúng ta cũng gặp các khái niệm tương tự về slot, tín hiệu và liên kết giữa chúng. Vậy nên các bạn sẽ không gặp khó khăn gì lớn khi làm việc với nó. Như đã nói, giao diện của Code ::Block mà chúng ta từng sử dụng được tạo ra nhờ wxWidgets. Nó cũng khá được, đúng không ?

.NET

.NET là thư viện để tạo ra các cửa sổ trong các hệ điều hành của Microsoft. Ngoài các tính năng liên quan đến GUI, .NET cũng cho phép lập trình viên giao tiếp sâu với Windows và cho phép truy cập nhiều dịch vụ qua mạng hay quản lý âm thanh. Tóm lại, đây là 1 thư viện vô cùng hoàn chỉnh. Hầu như mọi chương trình mà chúng ta biết trên Windows ngày nay đều sử dụng nó. 1 bộ công cụ không thể bỏ qua khi làm việc trên những hệ điều hành này. Thêm vào đó, tài liêu hướng dẫn của nó rất đầy đủ, giúp chúng ta tìm ra thông tin cần thiết 1 cách dễ dàng và nhanh chóng. Có 1 vài dự án có tham vọng mang thư viện này lên nền tảng Linux và Mac nhưng thành công vẫn còn rất hạn chế.

Thao tác với âm thanh

Sự lựa chọn trong lĩnh vực này thì dễ dàng hơn nhiều. Đương nhiên là vẫn có rất nhiều thư viện cho phép chúng ta quản lý âm thanh, thế nhưng trong đó có 1 đối thủ nặng ký có thể đè bẹp cả đống thư viện khác do sự vượt trội của bản thân khiến tôi không hề có nhiều do dự khi lựa chọn để giới thiệu. Tên nó là FMOD EX. Chỉ cần biết là tất cả các trò chơi hiện nay đều sử dụng nó là đủ hiểu rồi đúng không.

Thư viện này cho phép thao tác với hầu hết các định dạng khác nhau của tệp âm thanh, từ wav đến mp3. Với FMOD EX, chúng ta có thể phát các đoạn âm thanh, biến đổi chúng, thêm bộ lọc, biến đổi, thêm hiệu ứng, vv… Hầu như không có giới hạn ! Đây là lựa chọn tối ưu hiện nay trong lĩnh vực này.

boost

Hiển nhiên, tôi sẽ không thể kết thúc bài học này mà không đề cập tới boost. Đây là thư viện không thể bỏ qua trong những năm gần đây. Nó cùng cấp gần trăm gói công cụ chuyên biệt cho các thao tác chuyên biệt. Đây gần như là 1 bản mở rộng của thư viện chuẩn. Mỗi gói công cụ của boost đều được chăm chút bởi những người nghiên cứu tin học. Vậy nên nói về hiệu quả và độ tối ưu thì thật là miễn chê.

Thật xin lỗi là tôi cũng không thể nói tất cả những tính năng của nó ở đây nếu không chúng ta sẽ lại có thêm 1 quyển sách dày cộp nữa. Tuy nhiên, nếu các bạn thật sự quan tâm thì có thể tìm hiểu về 1 vài vấn đề sau đây :

  • Các công cụ toán học (phát sinh giá trị ngẫu nhiên, các hàm phức tạp, ma trận, thống kê, vv…)
  • Con trỏ thông minh : tính năng quản lý bộ nhớ thông minh, giúp tránh các sai lầm nguy hiểm có thể mắc phải khi thao tác với bộ nhớ.
  • Các công cụ làm việc với mạng lưới.
  • Các hàm thao tác với với thời gian, ngày tháng.
  • Các hàm quản lý gia phả tệp
  • Công cụ thao tác với các định dạng hình ảnh
  • Công cụ quản lý bộ xử lý nhiều nhân
  • Công cụ cho phép thực thi Python trong mã C++

Hầu như trong đấy có tất cả mọi thứ. Phần lớn các tính năng được cung cấp dưới dạng các lớp mẫu và được tối ưu hóa khi biên dịch. Vậy nên, theo thiển ý của tôi, đừng ngại tìm hiểu và sử dụng, thậm chi lạm dụng boost.

Các bạn không hề cô độc !

Đương nhiên là danh sách trên đây không thể liệt kê tất cả mọi thứ. Điều quan trọng là các bạn tìm ra được công cụ hay tính mình cần và cảm thấy thoải mải khi sử dụng. Đừng ngại tra cứu mạng để biết thêm về tất cả những lựa chọn có thể có.

Thêm nữa lúc nào các bạn cũng có thể đặt câu hỏi trên Lập trình Tân binh !

Giáo trình C++ dừng lại ở đây nhưng con đường của các bạn thì chắc chắn chỉ vừa bắt đầu. Vậy nên xin được gửi lời chúc thành công trên đoạn đường còn rất dài phía trước.

Chỉ hy vọng các bạn đã học được những thứ các bạn chờ đợi và tâm lý sẵn sàng làm việc với bất cứ dự án nào.

Và 1 ngày nào đó, khi các bạn lưỡng lự không biết nên tiếp tục tìm hiểu về điều gì, hy vọng bài học này sẽ lại có thể giúp các bạn có thêm ý tưởng về những điều mới mẻ cần khám phá trong thế giới tin học luôn thay đổi từng ngày.

Chào thân ái và quyết thắng !