Skip navigation.

Thanh Binh's Blog-CCN-HUT-51

The best way to predict Ur furture is to create it ! --Only for studying purpose

Tổng quan về UML

Ngôn ngữ mô hình hóa thống nhất (tiếng Anh: Unified Modeling Language, viết tắt thành UML) là một ngôn ngữ mô hình gồm các ký hiệu đồ họa mà các phương pháp hướng đối tượng sử dụng để thiết kế các hệ thống thông tin một cách nhanh chóng.
1- UML và các giai đoẠn cỦa chu trình phát triỂn phẦn mỀm
1.1- Giai đoạn nghiên cứu sơ bộ:
UML đưa ra khái niệm Use Case để nắm bắt các yêu cầu của khách hàng (người sử dụng). UML sử dụng biểu đồ Use case (Use Case Diagram) để nêu bật mối quan hệ cũng như sự giao tiếp với hệ thống.
Qua phương pháp mô hình hóa Use case, các tác nhân (Actor) bên ngoài quan tâm đến hệ thống sẽ được mô hình hóa song song với chức năng mà họ đòi hỏi từ phía hệ thống (tức là Use case). Các tác nhân và các Use case được mô hình hóa cùng các mối quan hệ và được miêu tả trong biểu đồ Use case của UML. Mỗi một Use case được mô tả trong tài liệu, và nó sẽ đặc tả các yêu cầu của khách hàng: Anh ta hay chị ta chờ đợi điều gì ở phía hệ thống mà không hề để ý đến việc chức năng này sẽ được thực thi ra sao.

1.2- Giai đoạn phân tích:
Giai đoạn phân tích quan tâm đến quá trình trừu tượng hóa đầu tiên (các lớp và các đối tượng) cũng như cơ chế hiện hữu trong phạm vi vấn đề. Sau khi nhà phân tích đã nhận biết được các lớp thành phần của mô hình cũng như mối quan hệ giữa chúng với nhau, các lớp cùng các mối quan hệ đó sẽ được miêu tả bằng công cụ biểu đồ lớp (class diagram) của UML. Sự cộng tác giữa các lớp nhằm thực hiện các Use case cũng sẽ được miêu tả nhờ vào các mô hình động (dynamic models) của UML. Trong giai đoạn phân tích, chỉ duy nhất các lớp có tồn tại trong phạm vi vấn đề (các khái niệm đời thực) là được mô hình hóa. Các lớp kỹ thuật định nghĩa chi tiết cũng như giải pháp trong hệ thống phần mềm, ví dụ như các lớp cho giao diện người dùng, cho ngân hàng dữ liệu, cho sự giao tiếp, trùng hợp, v.v..., chưa phải là mối quan tâm của giai đoạn này.

1.3- Giai đoạn thiết kế:
Trong giai đoạn này, kết quả của giai đoạn phân tích sẽ được mở rộng thành một giải pháp kỹ thuật. Các lớp mới sẽ được bổ sung để tạo thành một hạ tầng cơ sở kỹ thuật: Giao diện người dùng, các chức năng để lưu trữ các đối tượng trong ngân hàng dữ liệu, giao tiếp với các hệ thống khác, giao diện với các thiết bị ngoại vi và các máy móc khác trong hệ thống, .... Các lớp thuộc phạm vi vấn đề có từ giai đoạn phân tích sẽ được "nhúng" vào hạ tầng cơ sở kỹ thuật này, tạo ra khả năng thay đổi trong cả hai phương diện: Phạm vi vấn đề và hạ tầng cơ sở. Giai đoạn thiết kế sẽ đưa ra kết quả là bản đặc tả chi tiết cho giai đoạn xây dựng hệ thống.

1.4- Giai đoạn xây dựng:
Trong giai đoạn xây dựng (giai đoạn lập trình), các lớp của giai đoạn thiết kế sẽ được biến thành những dòng code cụ thể trong một ngôn ngữ lập trình hướng đối tượng cụ thể (không nên dùng một ngôn ngữ lập trình hướng chức năng!). Phụ thuộc vào khả năng của ngôn ngữ được sử dụng, đây có thể là một công việc khó khăn hay dễ dàng. Khi tạo ra các mô hình phân tích và thiết kế trong UML, tốt nhất nên cố gắng né tránh việc ngay lập tức biến đổi các mô hình này thành các dòng code. Trong những giai đoạn trước, mô hình được sử dụng để dễ hiểu, dễ giao tiếp và tạo nên cấu trúc của hệ thống; vì vậy, vội vàng đưa ra những kết luận về việc viết code có thể sẽ thành một trở ngại cho việc tạo ra các mô hình chính xác và đơn giản. Giai đoạn xây dựng là một giai đoạn riêng biệt, nơi các mô hình được chuyển thành code.

1.5- Thử nghiệm:
Như đã trình bày trong phần Chu Trình Phát Triển Phần Mềm, một hệ thống phần mềm thường được thử nghiệm qua nhiều giai đoạn và với nhiều nhóm thử nghiệm khác nhau. Các nhóm sử dụng nhiều loại biểu đồ UML khác nhau làm nền tảng cho công việc của mình: Thử nghiệm đơn vị sử dụng biểu đồ lớp (class diagram) và đặc tả lớp, thử nghiệm tích hợp thường sử dụng biểu đồ thành phần (component diagram) và biểu đồ cộng tác (collaboration diagram), và giai đoạn thử nghiệm hệ thống sử dụng biểu đồ Use case (use case diagram) để đảm bảo hệ thống có phương thức hoạt động đúng như đã được định nghĩa từ ban đầu trong các biểu đồ này.
2- Các thành phẦn cỦa ngôn ngỮ UML
Ngôn ngữ UML bao gồm một loạt các phần tử đồ họa (graphic element) có thể được kếp hợp với nhau để tạo ra các biểu đồ. Bởi đây là một ngôn ngữ, nên UML cũng có các nguyên tắc để kết hợp các phần tử đó.
Một số những thành phần chủ yếu của ngôn ngữ UML:
Hướng nhìn (view): Hướng nhìn chỉ ra những khía cạnh khác nhau của hệ thống cần phải được mô hình hóa. Một hướng nhìn không phải là một bản vẽ, mà là một sự trừu tượng hóa bao gồm một loạt các biểu đồ khác nhau. Chỉ qua việc định nghĩa của một loạt các hướng nhìn khác nhau, mỗi hướng nhìn chỉ ra một khía cạnh riêng biệt của hệ thống, người ta mới có thể tạo dựng nên một bức tranh hoàn thiện về hệ thống. Cũng chính các hướng nhìn này nối kết ngôn ngữ mô hình hóa với quy trình được chọn cho giai đoạn phát triển.
Biểu đồ (diagram): Biểu đồ là các hình vẽ miêu tả nội dung trong một hướng nhìn. UML có tất cả 9 loại biểu đồ khác nhau được sử dụng trong những sự kết hợp khác nhau để cung cấp tất cả các hướng nhìn của một hệ thống.
Phần tử mô hình hóa (model element): Các khái niệm được sử dụng trong các biểu đồ được gọi là các phần tử mô hình, thể hiện các khái niệm hướng đối tượng quen thuộc. Ví dụ như lớp, đối tượng, thông điệp cũng như các quan hệ giữa các khái niệm này, bao gồm cả liên kết, phụ thuộc, khái quát hóa. Một phần tử mô hình thường được sử dụng trong nhiều biểu đồ khác nhau, nhưng nó luôn luôn có chỉ một ý nghĩa và một kí hiệu.
Cơ chế chung: Cơ chế chung cung cấp thêm những lời nhận xét bổ sung, các thông tin cũng như các quy tắc ngữ pháp chung về một phần tử mô hình; chúng còn cung cấp thêm các cơ chế để có thể mở rộng ngôn ngữ UML cho phù hợp với một phương pháp xác định (một quy trình, một tổ chức hoặc một người dùng).
3 Hướng nhìn

3.1- Hướng nhìn Use case (Use case View):
Hướng nhìn Use case miêu tả chức năng của hệ thống sẽ phải cung cấp do được tác nhân từ bên ngoài mong đợi. Tác nhân là thực thể tương tác với hệ thống; đó có thể là một người sử dụng hoặc là một hệ thống khác. Hướng nhìn Use case là hướng nhìn dành cho khách hàng, nhà thiết kế, nhà phát triển và người thử nghiệm; nó được miêu tả qua các biểu đồ Use case (use case diagram) và thỉnh thoảng cũng bao gồm cả các biểu đồ hoạt động (activity diagram). Cách sử dụng hệ thống nhìn chung sẽ được miêu tả qua một loạt các Use case trong hướng nhìn Use case, nơi mỗi một Use case là một lời miêu tả mang tính đặc thù cho một tính năng của hệ thống (có nghĩa là một chức năng được mong đợi).
Hướng nhìn Use case mang tính trung tâm, bởi nó đặt ra nội dung thúc đẩy sự phát triển các hướng nhìn khác. Mục tiêu chung của hệ thống là cung cấp các chức năng miêu tả trong hướng nhìn này – cùng với một vài các thuộc tính mang tính phi chức năng khác – vì thế hướng nhìn này có ảnh hưởng đến tất cả các hướng nhìn khác. Hướng nhìn này cũng được sử dụng để thẩm tra (verify) hệ thống qua việc thử nghiệm xem hướng nhìn Use case có đúng với mong đợi của khách hàng (Hỏi: "Đây có phải là thứ bạn muốn") cũng như có đúng với hệ thống vừa được hoàn thành (Hỏi: "Hệ thống có hoạt động như đã đặc tả?”).

3.2- Hướng nhìn logic (Logical View):
Hướng nhìn logic miêu tả phương thức mà các chức năng của hệ thống sẽ được cung cấp. Chủ yếu nó được sử dụng cho các nhà thiết kế và nhà phát triển. Ngược lại với hướng nhìn Use case, hướng nhìn logic nhìn vào phía bên trong của hệ thống. Nó miêu tả kể cả cấu trúc tĩnh (lớp, đối tượng, và quan hệ) cũng như sự tương tác động sẽ xảy ra khi các đối tượng gửi thông điệp cho nhau để cung cấp chức năng đã định sẵn. Hướng nhìn logic định nghĩa các thuộc tính như trường tồn (persistency) hoặc song song (concurrency), cũng như các giao diện cũng như cấu trúc nội tại của các lớp.
Cấu trúc tĩnh được miêu tả bằng các biểu đồ lớp (class diagram) và biểu đồ đối tượng (object diagram). Quá trình mô hình hóa động được miêu tả trong các biểu đồ trạng thái (state diagram), biểu đồ trình tự (sequence diagram), biểu đồ tương tác (collaboration diagram) và biểu đồ hoạt động (activity diagram).

3.3- Hướng nhìn thành phần (Component View):
Là một lời miêu tả của việc thực thi các modul cũng như sự phụ thuộc giữa chúng với nhau. Nó thường được sử dụng cho nhà phát triển và thường bao gồm nhiều biểu đồ thành phần. Thành phần ở đây là các modul lệnh thuộc nhiều loại khác nhau, sẽ được chỉ ra trong biểu đồ cùng với cấu trúc cũng như sự phụ thuộc của chúng. Các thông tin bổ sung về các thành phần, ví dụ như vị trí của tài nguyên (trách nhiệm đối với một thành phần), hoặc các thông tin quản trị khác, ví dụ như một bản báo cáo về tiến trình của công việc cũng có thể được bổ sung vào đây.
3.4- Hướng nhìn song song (Concurrency View):
Hướng nhìn song song nhắm tới sự chia hệ thống thành các qui trình (process) và các bộ xử lý (processor). Khía cạnh này, vốn là một thuộc tính phi chức năng của hệ thống, cho phép chúng ta sử dụng một cách hữu hiệu các nguồn tài nguyên, thực thi song song, cũng như xử lý các sự kiện không đồng bộ từ môi trường. Bên cạnh việc chia hệ thống thành các tiểu trình có thể được thực thi song song, hướng nhìn này cũng phải quan tâm đến vấn đề giao tiếp và đồng bộ hóa các tiểu trình đó.
Hướng nhìn song song giành cho nhà phát triển và người tích hợp hệ thống, nó bao gồm các biểu đồ động (trạng thái, trình tự, tương tác và hoạt động) cùng các biểu đồ thực thi (biểu đồ thành phần và biểu đồ triển khai).

3.5- Hướng nhìn triển khai (Deployment View):
Cuối cùng, hướng nhìn triển khai chỉ cho chúng ta sơ đồ triển khai về mặt vật lý của hệ thống, ví dụ như các máy tính cũng như các máy móc và sự liên kết giữa chúng với nhau. Hướng nhìn triển khai giành cho các nhà phát triển, người tích hợp cũng như người thử nghiệm hệ thống và được thể hiện bằng các biểu đồ triển khai. Hướng nhìn này cũng bao gồm sự ánh xạ các thành phần của hệ thống vào cấu trúc vật lý; ví dụ như chương trình nào hay đối tượng nào sẽ được thực thi trên máy tính nào.

4. Biểu đồ
4.1Biểu đồ Use case (Use Case Diagram):
Một biểu đồ Use case chỉ ra một số lượng các tác nhân ngoại cảnh và mối liên kết của chúng đối với Use case mà hệ thống cung cấp (nhìn hình 3.2). Một Use case là một lời miêu tả của một chức năng mà hệ thống cung cấp. Lời miêu tả Use case thường là một văn bản tài liệu, nhưng kèm theo đó cũng có thể là một biểu đồ hoạt động. Các Use case được miêu tả duy nhất theo hướng nhìn từ ngoài vào của các tác nhân (hành vi của hệ thống theo như sự mong đợi của người sử dụng), không miêu tả chức năng được cung cấp sẽ hoạt động nội bộ bên trong hệ thống ra sao. Các Use case định nghĩa các yêu cầu về mặt chức năng đối với hệ thống.


4.2Biểu đồ lớp (Class Diagram):
Một biểu đồ lớp chỉ ra cấu trúc tĩnh của các lớp trong hệ thống (nhìn hình 3.3). Các lớp là đại diện cho các “vật” được xử lý trong hệ thống. Các lớp có thể quan hệ với nhau trong nhiều dạng thức: liên kết (associated - được nối kết với nhau), phụ thuộc (dependent - một lớp này phụ thuộc vào lớp khác), chuyên biệt hóa (specialized - một lớp này là một kết quả chuyên biệt hóa của lớp khác), hay đóng gói ( packaged - hợp với nhau thành một đơn vị). Tất cả các mối quan hệ đó đều được thể hiện trong biểu đồ lớp, đi kèm với cấu trúc bên trong của các lớp theo khái niệm thuộc tính (attribute) và thủ tục (operation). Biểu đồ được coi là biểu đồ tĩnh theo phương diện cấu trúc được miêu tả ở đây có hiệu lực tại bất kỳ thời điểm nào trong toàn bộ vòng đời hệ thống.
Một hệ thống thường sẽ có một loạt các biểu đồ lớp – chẳng phải bao giờ tất cả các biểu đồ lớp này cũng được nhập vào một biểu đồ lớp tổng thể duy nhất – và một lớp có thể tham gia vào nhiều biểu đồ lớp.


4.3 Biểu đồ đối tượng (Object Diagram):
Một biểu đồ đối tượng là một phiên bản của biểu đồ lớp và thường cũng sử dụng các ký hiệu như biểu đồ lớp. Sự khác biệt giữa hai loại biểu đồ này nằm ở chỗ biểu đồ đối tượng chỉ ra một loạt các đối tượng thực thể của lớp, thay vì các lớp. Một biểu đồ đối tượng vì vậy là một ví dụ của biểu đồ lớp, chỉ ra một bức tranh thực tế có thể xảy ra khi hệ thống thực thi: bức tranh mà hệ thống có thể có tại một thời điểm nào đó. Biểu đồ đối tượng sử dụng chung các ký hiệu của biểu đồ lớp, chỉ trừ hai ngoại lệ: đối tượng được viết với tên được gạch dưới và tất cả các thực thể trong một mối quan hệ đều được chỉ ra (nhìn hình 3.4).
Biểu đồ đối tượng không quan trọng bằng biểu đồ lớp, chúng có thể được sử dụng để ví dụ hóa một biểu đồ lớp phức tạp, chỉ ra với những thực thể cụ thể và những mối quan hệ như thế thì bức tranh toàn cảnh sẽ ra sao. Một biểu đồ đối tượng thường thường được sử dụng làm một thành phần của một biểu đồ cộng tác (collaboration), chỉ ra lối ứng xử động giữa một loạt các đối tượng.

4.4Biểu đồ trạng thái (State Diagram):
Một biểu đồ trạng thái thường là một sự bổ sung cho lời miêu tả một lớp. Nó chỉ ra tất cả các trạng thái mà đối tượng của lớp này có thể có, và những sự kiện (event) nào sẽ gây ra sự thay đổi trạng thái (hình 3.5). Một sự kiện có thể xảy ra khi một đối tượng tự gửi thông điệp đến cho nó - ví dụ như để thông báo rằng một khoảng thời gian được xác định đã qua đi – hay là một số điều kiện nào đó đã được thỏa mãn. Một sự thay đổi trạng thái được gọi là một sự chuyển đổi trạng thái (State Transition). Một chuyển đổi trạng thái cũng có thể có một hành động liên quan, xác định điều gì phải được thực hiện khi sự chuyển đổi trạng thái này diễn ra.
Biểu đồ trạng thái không được vẽ cho tất cả các lớp, mà chỉ riêng cho những lớp có một số lượng các trạng thái được định nghĩa rõ ràng và hành vi của lớp bị ảnh hưởng và thay đổi qua các trạng thái khác nhau. Biểu đồ trạng thái cũng có thể được vẽ cho hệ thống tổng thể. Biểu đồ trạng thái được miêu tả chi tiết hơn trong chương sau (Mô hình động).
4.5Biểu đồ trình tự (Sequence Diagram):
Một biểu đồ trình tự chỉ ra một cộng tác động giữa một loạt các đối tượng (xem hình 3.6). Khía cạnh quan trọng của biểu đồ này là chỉ ra trình tự các thông điệp (message) được gửi giữa các đối tượng. Nó cũng chỉ ra trình tự tương tác giữa các đối tượng, điều sẽ xảy ra tại một thời điểm cụ thể nào đó trong trình tự thực thi của hệ thống. Các biểu đồ trình tự chứa một loạt các đối tượng được biểu diễn bằng các đường thẳng đứng. Trục thời gian có hướng từ trên xuống dưới trong biểu đồ, và biểu đồ chỉ ra sự trao đổi thông điệp giữa các đối tượng khi thời gian trôi qua. Các thông điệp được biểu diễn bằng các đường gạch ngang gắn liền với mũi tên (biểu thị thông điệp) nối liền giữa những đường thẳng đứng thể hiện đối tượng. Trục thời gian cùng những lời nhận xét khác thường sẽ được đưa vào phần lề của biểu đồ.



4.6 Biểu đồ cộng tác (Collaboration Diagram):
Một biểu đồ cộng tác chỉ ra một sự cộng tác động, cũng giống như một biểu đồ trình tự. Thường người ta sẽ chọn hoặc dùng biểu đồ trình tự hoặc dùng biểu đồ cộng tác. Bên cạnh việc thể hiện sự trao đổi thông điệp (được gọi là tương tác), biểu đồ cộng tác chỉ ra các đối tượng và quan hệ của chúng (nhiều khi được gọi là ngữ cảnh). Việc nên sử dụng biểu đồ trình tự hay biểu đồ cộng tác thường sẽ được quyết định theo nguyên tắc chung sau: Nếu thời gian hay trình tự là yếu tố quan trọng nhất cần phải nhấn mạnh thì hãy chọn biểu đồ trình tự; nếu ngữ cảnh là yếu tố quan trọng hơn, hãy chọn biểu đồ cộng tác. Trình tự tương tác giữa các đối tượng được thể hiện trong cả hai loại biểu đồ này.
Biểu đồ cộng tác được vẽ theo dạng một biểu đồ đối tượng, nơi một loạt các đối tượng được chỉ ra cùng với mối quan hệ giữa chúng với nhau (sử dụng những ký hiệu như trong biểu đồ lớp/ biểu đồ đối tượng). Các mũi tên được vẽ giữa các đối tượng để chỉ ra dòng chảy thông điệp giữa các đối tượng. Các thông điệp thường được đính kèm theo các nhãn (label), một trong những chức năng của nhãn là chỉ ra thứ tự mà các thông điệp được gửi đi. Nó cũng có thể chỉ ra các điều kiện, chỉ ra những giá trị được trả về, v.v... Khi đã làm quen với cách viết nhãn, một nhà phát triển có thể đọc biểu đồ cộng tác và tuân thủ theo dòng thực thi cũng như sự trao đổi thông điệp. Một biểu đồ cộng tác cũng có thể chứa cả các đối tượng tích cực (active objects), hoạt động song song với các đối tượng tích cực khác (hình 3.7).
4.7Biểu đồ hoạt động (Activity Diagram):
Một biểu đồ hoạt động chỉ ra một trình tự lần lượt của các hoạt động (activity) (hình 3.8). Biểu đồ hoạt động thường được sử dụng để miêu tả các hoạt động được thực hiện trong một thủ tục, mặc dù nó cũng có thể được sử dụng để miêu tả các dòng chảy hoạt động khác, ví dụ như trong một Use case hay trong một trình tự tương tác. Biểu đồ hoạt động bao gồm các trạng thái hành động, chứa đặc tả của một hoạt động cần phải được thực hiện (một hành động - action). Một trạng thái hành động sẽ qua đi khi hành động được thực hiện xong (khác với biểu đồ trạng thái: một trạng thái chỉ chuyển sang trạng thái khác sau khi đã xảy ra một sự kiện rõ ràng !). Dòng điều khiển ở đây chạy giữa các trạng thái hành động liên kết với nhau. Biểu đồ còn có thể chỉ ra các quyết định, các điều kiện, cũng như phần thực thi song song của các trạng thái hành động. Biểu đồ ngoài ra còn có thể chứa các loại đặc tả cho các thông điệp được gửi đi hoặc được nhận về, trong tư cách là thành phần của hành động được thực hiện.

4.8Biểu đồ thành phần (Component Diagram):
Một biểu đồ thành phần chỉ ra cấu trúc vật lý của các dòng lệnh (code) theo khái niệm thành phần code. Một thành phần code có thể là một tập tin source code, một thành phần nhị phân (binary) hay một thành phần thực thi được (executable). Một thành phần chứa các thông tin về các lớp logic hoặc các lớp mà nó thi hành, như thế có nghĩa là nó tạo ra một ánh xạ từ hướng nhìn logic vào hướng nhìn thành phần. Biểu đồ thành phần cũng chỉ ra những sự phụ thuộc giữa các thành phần với nhau, trợ giúp cho công việc phân tích hiệu ứng mà một thành phần được thay đổi sẽ gây ra đối với các thành phần khác. Thành phần cũng có thể được miêu tả với bất kỳ loại giao diện nào mà chúng bộc lộ, ví dụ như giao diện OLE/COM; và chúng có thể được nhóm góp lại với nhau thành từng gói (package).
4.9Biểu đồ triển khai (Deployment Diagram):
Biểu đồ triển khai chỉ ra kiến trúc vật lý của phần cứng cũng như phần mềm trong hệ thống. Bạn có thể chỉ ra từng máy tính cụ thể và từng trang thiết bị cụ thể (node) đi kèm sự nối kết giữa chúng với nhau, bạn cũng có thể chỉ ra loại của các mối nối kết đó. Bên trong các nút mạng (node), các thành phần thực thi được cũng như các đối tượng sẽ được xác định vị trí để chỉ ra những phần mềm nào sẽ được thực thi tại những nút mạng nào. Bạn cũng có thể chỉ ra sự phụ thuộc giữa các thành phần.
Biểu đồ triển khai chỉ ra hướng nhìn triển khai, miêu tả kiến trúc vật lý thật sự của hệ thống. Đây là một hướng nhìn rất xa lối miêu tả duy chức năng của hướng nhìn Use case. Mặc dù vậy, trong một mô hình tốt, người ta có thể chỉ tất cả những con đường dẫn từ một nút mạng trong một kiến trúc vật lý cho tới những thành phần của nó, cho tới lớp mà nó thực thi, cho tới những tương tác mà các đối tượng của lớp này tham gia để rồi cuối cùng, tiến tới một Use case. Rất nhiều hướng nhìn khác nhau của hệ thống được sử dụng đồng thời để tạo ra một lời miêu tả thấu đáo đối với hệ thống trong sự tổng thể của nó.

Huong doi tuong (OOP) voi C++

C++ Các chức năng hướng đối tượng

C++ dẫn nhập thêm một số chức năng hướng đối tượng (OO) lên C. Nó cung cấp các lớp mà có 4 chức năng thông dụng trong các ngôn ngữ OO : tính trừu tuợng, tính bao đóng, tính đa hình, và tính kế thừa.

Lưu ý: trong phần này các từ "hàm nội tại", "phương pháp", hay "hàm" đều có cùng một nghĩa là "phương pháp thuộc về một lớp".
[sửa] Tính đóng

C++ xây dựng tính đóng bằng cách cho phép mọi thành viên của một lớp có thể được khai báo bằng các từ khoá public, private, hay protected. (xem thêm các khái niệm cơ bản trong ngôn ngữ OO). Một thành viên private chỉ có thể được truy cập từ các phương pháp (hàm nội tại) là thành viên của chính lớp đó hay được truy cập từ các hàm và các lớp được đặc biệt cho phép sử dụng bằng cách dùng từ khóa friend. Một thành viên protected của một lớp sẽ có thể truy cập được từ các thành viên (nào đó) của các lớp có tính kế thừa của nó hay cũng có thể truy cập được từ các thành viện của chính lớp đó và của mọi thành viên friend.

Nguyên lý của OO là mọi và chỉ có các hàm là có thể truy cập được đến các giá trị nội tại của cùng lớp thì nên có tính đóng. C++ có hỗ trợ đặc tính này (qua các hàm thành viên và các hàm friend), nhưng C++ lại không là yêu cầu bắt buộc: người lập trình có thể khai báo các phần hay tất cả các giá trị nội tại là công cộng (public), và cũng cho phép làm cho toàn bộ lớp trở thành công cộng. Lí do là vì C++ hổ trợ không chỉ lập trình hướng đối tượng mà còn hổ trợ các mẫu hình yếu hơn như là lập trình mô-đun.

Một thói quen tốt cần có trong thực hành là khai báo mọi dữ liệu đều là riêng tư (private), hay ít nhất ở dạng bảo tồn, và sau đó, tạo ra một giao diện nhỏ (thông qua các phương pháp) cho người dùng của lớp này dấu đi các chi tiết thiết lập bên trong.
[sửa] Tính đa hình

Khái niệm đa hình được dùng khá rộng rãi và là khái niệm bị lạm dụng cũng như không được định nghĩa rõ ràng.

Nói chung tính đa hình trong lập trình hướng muốn nói đến 1 đoạn code nhưng trong 2 trường hợp khác nhau có thể xuất ra 2 kết quả khác nhau. Vì tính chất ra nhiều kết quả khác nhau này nên nó được gọi là đa hình.

Trong trường hợp của C++, khái niệm này thường được nối kết với các tên của các hàm thành viên. Các hàm thành viên này có cùng tên, sự khác nhau chỉ có thể được dựa vào một hay cả hai yếu tố sau:

1. Số lượng và kiểu của các đối số (tức là nguyên mẫu của hàm) -- Tính chất này gọi là đa hình tĩnh (static polymorphism)
2. Kiểu lớp mà thực thể thực sự thuộc vào. Tính chất này được dùng khi hàm thành viên được định nghĩa là hàm ảo qua từ khóa virtual -- tính chất này gọi là đa hình động (dynamic polymorphism)

Khi được gọi thì chương trình sẽ tùy theo hai yếu tố trên để xác định chính xác hàm nào phải được thực thi trong số các hàm cùng tên.

Thí dụ sau đây mô tả tính đa hình:

1.

/* Static polymorphism */

2.



3.

extern void SendJobToDevice(PrintJobText *, DeviceLaser *);

4.

extern void SendJobToDevice(PrintJobText *, DeviceJet *);

5.

extern void SendJobToDevice(PrintJobHTML *, DeviceLaser *);

6.

extern void SendJobToDevice(PrintJobHTML *, DeviceJet *);

7.

...

8.

SendJobToDevice(printJob, device);

9.



10.

/* Dynamic polymorphism */

11.



12.

class Device {

13.

public:

14.

virtual void print(PrintJob*);

15.

...

16.

};

17.



18.

PrintJob *printJob;

19.

Device *device;

20.

...

21.

device->print(printJob);

22.

// Note that since C++ does not have multiple dispatch, the above

23.

// function call is polymorphic based only on the device's type.

Ví dụ thứ hai về tính đa hình động:

1.

class Nguoi

2.

{

3.

public:

4.

virtual void Chao() // Hàm ảo

5.

{

6.

cout << "Toi chua biet chao";

7.

};

8.

};

9.

//------------------

10.

class NguoiViet : public Nguoi

11.

{

12.

public:

13.

void Chao()

14.

{

15.

cout << "Xin chao.";

16.

}

17.

};

18.

//------------------

19.

class NguoiAnh : public Nguoi

20.

{

21.

public:

22.

void Chao()

23.

{

24.

cout << "Hello.";

25.

}

26.

};

27.

//------------------

28.

void main()

29.

{

30.

Nguoi *n; NguoiViet nv; NguoiAnh na;

31.

n = &nv;

32.

n->Chao(); // (*)

33.

n = &na;

34.

n->Chao(); // cùng dòng code voi (*) nhưng lại cho kết quả khác

35.

}

Trong C, thì đa hình (động) có thể đạt tới bằng cáh dùng từ khóa switch hay dùng con trỏ hàm.

C++ còn cung cấp hai tính năng độc đáo cho đa hình là:

* Sự tải bội (overloading): Cho phép một toán tử hay một hàm có những ứng xử khác nhau phụ thuộc vào kiểu của các toán hạng hay các tham số tại thời điểm toán tử hay hàm được triệu gọi.

Ví dụ, ta có thể định nghĩa hai hàm trùng tên như sau: float Demo(float a, float b) {return a + b;} và int Demo(int a, int b) {return a - b;} Ta cũng có thể tải bội phép cộng cho lớp MATRIX để có thể viết được C = A + B khi A, B và C có kiểu MATRIX.

* Tính ảo (virtual): Cho phép một phương thức (hàm thành viên hoặc toán tử) của lớp có ứng xử khác nhau phụ thuộc vào sự kế thừa của lớp con cháu (Xem phương thức Chao() trong ví dụ trên. Onminh (thảo luận) 17:22, ngày 28 tháng 9 năm 2009 (UTC)

Hai tính năng trên cho phép chưong trình định ra nhiều sự thiết lập khác nhau của một hàm để sử dụng ứng với các kiểu (khác nhau) của các đối tượng.

Việc quá tải hàm cho phép các chương trình khai báo nhiều hàm có chung một tên (ngay cả việc các hàm này thuộc cùng một lớp). Các hàm này phân biệt được bởi số lượng và kiểu của các tham số. Thí dụ, một chương trình có thể có khai báo 3 hàm sau:

1.

void pageUser(int userid);

2.

void pageUser(int userid, string message);

3.

void pageUser(string username);

Sau, đó, khi trình dịch đọc phải câu lệnh có gọi tới hàm pageUser(), thì mó sẽ xác định xem đó là hàm nào tùy dựa trên số lượng và kiểu của các đối số đã được đưa vào (tức là dựa vào sự khác nhau của các nguyên mẫu của những hàm này). Lý do ta gọi kiểu quá tải hàm này là đa hình tĩnh vì nó được phân lập trong thời gian dịch mã.

Chú ý: trình dịch sẽ không phân biệt khác nhau về kiểu trả về, do đó không thể quá tải hai hàm hoàn toàn giống nhau trong cùng một lớp mà lại chỉ khác nhau về kiểu trả về.

Quá tải toán tử (operation overloading) là một dạng của quá tải hàm. Nó là một trong những đặc tích của C++ bị nhiều tranh cãi nhất. Nhiều người cho rằng việc quá tải toán tử đã bị lạm dụng quá đáng, nhưng nhiều người khác nghĩ rằng đây là công cụ rất mạnh để tăng cường sự biểu thị (qua kí các hiệu toán tử).
Toán tử là một trong những kí hiệu đã được định nghĩa trong ngôn ngữ C++ đóng vai trò của các toán tử để thực hiện các phép toán trên các kiểu dữ liệu. Quá tải toán tử được hiểu là quá trình hay phương thức để tái sử dụng một toán tử sẳn có để định nghĩa và dùng cho một phép toán khác.

Danh sách các toán tử có thể thực hiện quá tải

+ - * / = < > += -= *= /= <<
>> <<= >>= == != <= >= ++ -- % & ^
! | ~ &= ^= |= && || %= [] () new delete

Việc quá tải hàm cho phép người lập trình định nghĩa nhiều phiên bản khác nhau của một hàm để dùng với các kiểu đối số khác nhau trong khi việc quá tải toán tử lại cho phép người lập trình định nghĩa nhiều phiên bản khác nhau của một toán tử để dùng với các kiểu phép toán khác nhau.

Integer& operator++();

thì chương trình này có thể dùng toán tử ++ vói các đối tượng của kiểu Integer. Thí dụ như:

1.

Integer a = 2;

2.

++a;

sẽ ứng xử tương đương với:

1.

Integer a = 2;

2.

a.operator++();

Trong phần lớn trường hợp, đoạn mã nguồn trên sẽ làm tăng giá trị của biến a lên 3. Tuy nhiên, lập trình viên viết lớp Integer có thể định nghĩa toán tử Integer::o:perator++() làm bất cứ gì lập trình viên muốn. Vì toán tử thường được dùng ngầm, lập trình viên không nên khai báo toán tử trừ trường hợp ý nghĩa của toán tử là rõ ràng và không gây nhầm lẫn. Tuy nhiên, có nhiều ý kiến cho rằng thư viện chuẩn C++ không tuân theo quy ước này. Ví dụ, đối tượng cout, được sử dụng để xuất ký tự ra màn hình có toán tử quá tải <<, nhiều người cho rằng toán tử << là không rõ ràng và vô nghĩa trong trường hợp muốn xuất ký tự ra màn hình do toán tử này cũng là toán tử được dùng trong phép tính dịch bit. Tuy nhiên, phần lớn lập trình viên cho rằng cách sử dụng toán tử << trong trường hợp cout là có thể chấp nhận được.

Tiêu bản C++ sử dụng rất nhiều tính đa hình tĩnh, trong đó bao gồm cả các toán tử được quá tải.

Hàm ảo cung cấp một kiểu đa hình khác. Trong trường hợp này, các đối tượng có cùng một lớp cơ sở có thể sử dụng một hàm một cách khác nhau. Ví dụ, lớp cơ sở PrintJob bao gồm hàm thành viên:

virtual int getPageCount(double pageWidth, double pageHeight)

Mỗi cách khác nhau của công việc in như là DoubleSpacedPrintJob, có thể trở thành phương pháp ưu tiên với một hàm mà có thể tính được gần đúng số trang của công việc in theo cách đó. Ngược lại, với việc quá tải hàm, các tham số của một hàm thành phần cho trước thì luôn luôn xác định và không đổi về số lượng và kiểu. Chỉ có kiểu của đối tượng (mà theo đó tên của phương pháp này được gọi) là có thay đổi.

Khi một hàm thành viên ảo của một đối tượng đuợc gọi thì trình dịch đôi khi không được kiểu của đối tượng này ở thời gian dịch và do đó không thể xác định hàm (quá tải) nào để gọi. Quyết định gọi này bởi vậy phải để vào thời gian thực thi. Trình dịch sẽ tạo ra các mã để kiểm tra lại kiểu của đối tượng ở thời gian thi hành và từ đó xác định hàm nào để gọi. Bởi vì việc xác định hàm chỉ xãy ra lúc chạy chương trình nên phương pháp quá tải hàm này được gọi là đa hình động.

Sự xác định và thi hành của một hàm trong thời gian thực thi gọi là điều phối động. Trong C++, việc này thường hoàn tất bằng cách dùng các bảng ảo.
[sửa] Tính kế thừa

Kế thừa từ một lớp cơ sở có thể được khai báo thông qua các đặc tính công cộng, bảo tồn, hay riêng tư. Những đặc tính này cho phép xác định khi nào các lớp dẫn xuất hay không liên quan có thể sử dụng các thành viên công cộng, bảo tồn, hay riêng tư của lớp cơ sở. Tuy nhiên, chỉ có sự kế thừa dạng công cộng là hoàn toàn theo đúng ý nghĩa của việc "kế thừa". Hai dạng khác thì ít được dùng hơn. Nếu các đặc tả này không được khai báo thì việc kế thừa được gán mặc định là dạng riêng tư cho lớp cơ sở và dạng công cộng cho một cấu trúc cơ sở.

Các lớp cơ sở có thể được khai báo là ảo (thông qua từ khóa virtual). Kế thừa ảo bảo đảm rằng chỉ có một thực thể của lớp cơ sở tồn tại trong đồ thị kế thừa, tránh được một số vấn đề mơ hồ của việc đa kế thừa.

Đa kế thừa cũng là một tính năng có nhiều tranh cãi trong C++. Tính đa kế thừa cho phép một lớp được dẫn xuất từ nhiều hơn một lớp cơ sở; điều này có thể dẫn tới một đồ thị phức tạp của các quan hệ kế thừa. Thí dụ, lớp "Buổi học" có thể kế thừa từ hai lớp "thời gian" và "bộ môn". Một số ngôn ngữ khác như Java , tiến hành cách thức tương tự bằng cách cho phép kế thừa của nhiều giao diện trong khi giới hạn số lượng của các lớp cơ sở (kế thừa) chỉ còn là một lớp. (giao diện, không như lớp, không cho phép thiết lập nội dung của các thành viên và do đó không thể có thực thể)
[sửa] Thiết kế của C++

Trong tác phẩm The Design and Evolution of C++ ISBN 0-201-54330-3, Bjarne Stroustrup miêu tả các quy tắc mà ông ta dùng cho việc thiết kế C++. Biết rõ các quy tắc này sẽ giúp hiểu được tại sao C++ lại đi theo cách riêng của nó. Sau đây là một tổng kết sơ lược của các quy tắc. Các chi tiết của chúng có thể được tìm thấy trong cuốn The Design and Evolution of C++.

* C++ được thiết kế để là một ngôn ngữ tổng quát có kiểu tĩnh mà lại hữu hiệu và năng động như C
* C++ được thiết kế nhằm hổ trợ trực tiếp và đầy đủ nhiều kiểu lập trình như là lập trình cấu trúc, sự Trừu tượng của dữ liệu, lập trình hướng đối tượng, và lập trình tổng quát.
* C++ được thiết kế để người lập trình có cơ hội lựa chọn ngay cả khi điều này có thể dẫn tới sự chọn lựa sai lầm của người lập trình.
* C++ được thiết kế để tương thích với C càng nhiều càng tốt, do đó, có cung ứng một sự chuyển đổi (ngôn ngữ) rất thuận tiện từ C.
* C++ tránh các chức năng mà chúng thuộc về dặc điểm riêng của nền tảng hay của mục đích chung chung.
* C++ không lệ thuộc vào các phần bổ sung cho các tính năng thừa
* C++ được thiết kế để hoạt động mà không cần phải có môi trường lập trình hoàn thiện.

Đọc thêm:

* Inside the C++ Object Model, cuốn sách đào sâu nội dung của C++ của Stanley B. Lippman, ông là người xây đựng và bảo trì C-front, một phiên bản thiết lập nguyên thủy của C++ tại Bell Labs. Sách này trình bày làm thế nào trình dịch C++ chuyển các câu lệnh vào sự thiết trí bên trong bộ nhớ.

[sửa] Lịch sử C++

Stroustrup đã bắt đầu làm việc với khái niệm lớp trong 1979. Ý tưởng tạo ra một ngôn ngữ mới bắt nguồn từ kinh nghiệm lập trình khi mà ông viết luận án tiến sĩ. Stroustrup nhận ra rằng Simula có nhiều tính năng hữu dụng cho việc phát triển một phần mềm lớn nhưng nó đã quá chậm trong ứng dụng thực tế, trong khi đó, BCPL lại nhanh nhưng ở cấp quá thấp và không tiện cho việc phát triển phần mềm lớn. Đến khi làm việc ở Bell Labs, thì ông gặp phải vấn đề trong việc phân tích nhân Unix với việc tính toán phân tán. Dùng lại kinh nghiệm lúc làm luận án tiến sĩ, Stroustrup cài thêm các tính năng giống như Simula vào trong C để nâng cao. C được chọn là vì đó là ngôn ngữ tổng quát, nhanh và năng động. Lần đầu tiên, các chức năng như là lớp, lớp dẫn xuất, kiểm tra kiểu mạnh, nội tuyến (inline), và đối số mặc định đã được thêm vào trong C. Lần xuất bản đầu tiên vào thị trường xảy ra trong tháng 11 1985.

Năm 1983, thì tên C với các lớp được đổi thành C++. các chức năng mới được thêm vào bao gồm hàm ảo, quá tải hàm và toán tử, tham chiếu, hằng, khả năng kiểm soát bộ nhớ của lưu trữ tự do, nâng cao việc kiểm soát kiểu, và lệnh chú giải kiểu (//).

Năm 1985, tác phẩm The C++ Programming Language được xuất bản lần đầu tiên, cung cấp một tài liệu tham khảo quan trọng cho ngôn ngữ nhưng đó chưa là một tiêu chuẩn chính thức.

Năm 1989 phiên bản C++ 2.0 phát hành. Các tính năng mới bao gồm đa kế thừa, lớp trừu tượng, hàm tĩnh, hàm thành viên hằng, và thành viên bảo tồn.

Năm 1990, cuốn The Annotated C++ Reference Manual được xuất bản cung cấp nền tảng cho tiêu chuẩn tương lai.

Phiên bản xuất bản sau đó có thêm các chức năng tiêu bản, ngoại lệ, không gian tên, chuyển kiểu cho toán tử new, và kiểu Boolean.

Khi C++ hình thành, thì thư viện chuẩn hoàn thiện với nó. Thư viện C++ đầu tiên thêm vào là IOSttream cung cấp cơ sở để thay thế các hàm C truyền thống như là printf và scanf. Sàu này, trong những thư viện chuẩn quan trọng nhất được thêm vào là Thư viện Tiêu bản Chuẩn.

Sau nhiều năm làm việc, có sự cộng tác giữa ANSI và hội đồng tiêu chuẩn hoá C++ của ISO để soạn thảo tiêu chuẩn ISO/IEC 14882:1998. Phiên bản tiêu chuẩn này được phát hành năm 1989, hội đồng tiếp tục xử lí các báo cáo trục trặc, và ấn hành một phiên bản sửa sai của chuẩn C++ trong năm 2003.

Không ai là chủ nhân của ngôn ngữ C++, nó hoàn toàn miễn phí khi dùng. Mặc dù vậy, các văn bản tiêu chuẩn thì không miễn phí.
[sửa] Sự phát triển trong tương lai

C++ tiếp tục phát triển để thỏa mản các nhu cầu tương lai. Đặc biết nhóm Boost.org, làm việc trên hầu hết các dạng và các khuyến cáo trong C++ cho Hội đồng Tiêu chuẩn C++ về các chức năng hoạt động tốt và các chức năng cần được cải thiện. Công việc hiện tại cho thấy bản năng đa mẫu hình của C++ sẽ ngày càng nhiều. Thí dụ: Công việc của Boost.org mở rộng rất mạnh chức năng của C++ và khả năng siêu lập trình (metaprogramming) của nó. Chuẩn C++ không đề cập về sự thiết lập của mã hóa tên (name decoration), xử lí ngoại lệ và sự thiết lập các tính năng đặc biệt khác, tạo mã đối tượng mà nó được làm ra từ những trình dịch không tương thích khác. Dù vậy, vẫn có những tiêu chuẩn khác từ các nhà sản xuất dùng cho những máy hay OS riêng biệt nhằm tiêu chuẩn hóa các trình dịch trên các nền tảng đó, thí dụ [1].

Các trình dịch cho đến gần đây (2004) vẫn lưỡng lự khi hỗ trợ toàn bộ chuẩn C++, đặc biệt là trong những lãnh vực của tiêu bản (đây là phần ngôn ngữ đã được công nhận hoàn toàn từ hội đồng tiêu chuẩn. Một điểm các biệt đáng nói nữa là từ khóa export, nhằm cho phép các định nghĩa của các tiêu bản được tách rời khỏi các khai báo của chúng. Trình dịch đầu tiên thiết kế kiểu này là Comeau C++, đầu năm 2003 (5 năm sau khi tiêu chuẩn đã được phát hành!); trong năm 2004, phiên bản beta trình dịch của Borland C++ Builder X cũng hỗ trợ dùng export. Cả hai trình dịch đó dựa trên mặt ngoài của EDG C++. Cũng cần lưu ý rằng nhiều sách cung cấp mã thí dụ cho việc thiết lập từ khóa export (Ivor Horton's Beginning ANSI C++, pg. 827) mà lại không dịch được, nhưng lại cũng không có tham khảo vấn dề này với việc (khó khăn) đã nêu trên. Những trình dịch khác như là Microsoft Visual C++ và GCC thì hoàn toàn không hỗ trợ nó. Herb Sutter, thư kí hội đồng tiêu chuẩn C++, có khuyến cáo rằng export sẽ được hủy bỏ trong các phiên bản tương lai của chuẩn C++ [2]. Nhưng quyết định tối hậu đã được đưa ra là giữ nguyên nó trong chuẩn C++.

Nhiều vấn đề về tiêu bản bao gồm các xây dựng như đặc biệt hóa tiêu bản từng phần, mà đã được hỗ trợ một cách nghèo nàn trong nhiều năm sau khi chuẩn C++ đã ra đời.
[sửa] Lịch sử của tên "C++"

Tên C++ được đặt ra bởi Rick Mascitti (giữa 1983) và lần đầu tiên được dùng trong tháng 12 1983. Trước đó, trong suốt thời kì nghiên cứu, khi ngôn ngữ phát triển đã được đề cập như là "C với các lớp". Toán tử ++ được nối vào với tên "C" (có nghĩa là tăng giá trị của C lên 1 đơn vị) được dùng theo cách đặt tên thông thường của việc dùng dấu + với ý nghĩa "nâng cao". Thí dụ: "Wikipedia+". Theo Stroustrup thì:

Cái tên C++ nhấn mạnh sự tiến hóa tự nhiên của các thay đổi từ C. C+ là tên của một ngôn ngữ lập trình cũ và không liên quan gì đến C hay C++.
[sửa] C++ không phải là C mở rộng

Trong khi nhiều mã nguồn viết trong C sẽ được dịch như là ngôn ngữ C++ mà không gặp trở ngại gì thì cũng có một số khác nhau giữa hai ngôn ngữ đã ngăn không cho C++ trở thành (ngôn ngữ) mở rộng của C. Chẳng hạn như C++ cấm gọi hàm main bên trong một chương trình, trong khi điều này hợp lệ trong C. Thêm vào đó C++ có nhiều giới hạn trong một số tính năng như là nó thiếu sự chuyển kiểu mặc định giữa các kiểu con trỏ không liên hệ nhau và cũng không cho phép một hàm được sử dụng nếu chưa khai báo.

Một vấn đè thường xãy ra khi chuyển dịch từ C sang C++ là nhiều từ khoá được thêm vào trong C++. Điều này có thể làm cho một số tên trong C trở thành bất hợp lệ trong C++. Thí dụ:

1.

struct template {

2.

int new;

3.

struct template *class;

4.

};

hợp lệ trong C nhưng không dùng đưọc trong C++ vì các từ khoá template, new và class.

Sự khác nhau còn xãy ra trong kiểu trình bày. Thí dụ như trong một cách cũ và truyền thống của việc khai báo trong C sau đây sẽ không được chấp thuận trong C++:

1.

int subtract(minuend, subtrahend)

2.

int minuend;

3.

int subtrahend;

4.

{

5.

return minuend - subtrahend;

6.

}

Theo yêu cầu mới trong C++ nên viết thành:

1.

int subtract(int minuend, int subtrahend)

2.

{

3.

return minuend - subtrahend;

4.

}

Virtual function in C++

C++ Virtual Function - Properties:

C++ virtual function is,

* A member function of a class
* Declared with virtual keyword
* Usually has a different functionality in the derived class
* A function call is resolved at run-time
The difference between a non-virtual c++ member function and a virtual member function is, the non-virtual member functions are resolved at compile time. This mechanism is called static binding. Where as the c++ virtual member functions are resolved during run-time. This mechanism is known as dynamic binding.

C++ Virtual Function - Reasons:

The most prominent reason why a C++ virtual function will be used is to have a different functionality in the derived class.

For example a Create function in a class Window may have to create a window with white background. But a class called CommandButton derived or inherited from Window, may have to use a gray background and write a caption on the center. The Create function for CommandButton now should have a functionality different from the one at the class called Window.
C++ Virtual function - Example:

This article assumes a base class named Window with a virtual member function named Create. The derived class name will be CommandButton, with our over ridden function Create.

     class Window // Base class for C++ virtual function example
     {
       public:
          virtual void Create() // virtual function for C++ virtual function example
          {
               cout <<"Base class Window"<<endl;
          }
     };

     class CommandButton : public Window
     {
       public:
          void Create()
          {
              cout<<"Derived class Command Button - Overridden C++ virtual function"<<endl;
          }
     };

     void main()
     {
         Window  *x, *y;
  
         x = new Window();
         x->Create();

         y = new CommandButton();
         y->Create();
     }

The output of the above program will be,
Base class Window
Derived class Command Button

If the function had not been declared virtual, then the base class function would have been called all the times. Because, the function address would have been statically bound during compile time. But now, as the function is declared virtual it is a candidate for run-time linking and the derived class function is being invoked.
C++ Virtual function - Call Mechanism:

Whenever a program has a C++ virtual function declared, a v-table is constructed for the class. The v-table consists of addresses to the virtual functions for classes and pointers to the functions from each of the objects of the derived class. Whenever there is a function call made to the c++ virtual function, the v-table is used to resolve to the function address. This is how the Dynamic binding happens during a virtual function call.

Virtual destructor :
Why a destructor has to be virtual, the reason is that we, programmers are very smart. We'll do days and nights of work to inherit and extend the functionality of an existing class which is being used, and say that we don't want to change the implementation/interface just for the sake of a new entrant. Let me explain this with an example.
bad code
#include <iostream.h>
class Base
{
       public:
          Base(){ cout<<"Constructor: Base"<<endl;}
          ~Base(){ cout<<"Destructor : Base"<<endl;}
};
class Derived: public Base
{
     //Doing a lot of jobs by extending the functionality
       public:
           Derived(){ cout<<"Constructor: Derived"<<endl;}
           ~Derived(){ cout<<"Destructor : Derived"<<endl;}
> };
void main()
{
        Base *Var = new Derived();
        delete Var;
}


Try executing this code, you'll see the difference. To our observation, the constructors are getting called in the proper order. But to the dread of a programmer of a large project
, the destructor of the derived class was not called at all.

This is where the virtual mechanism comes into our rescue. By making the Base class Destructor virtual, both the destructors will be called in order. The following is the corrected sample.
Kool code
#include <iostream.h>
class Base
{
       public:
          Base(){ cout<<"Constructor: Base"<<endl;}
          virtual ~Base(){ cout<<"Destructor : Base"<<endl;}
};
class Derived: public Base
{
     //Doing a lot of jobs by extending the functionality
       public:
           Derived(){ cout<<"Constructor: Derived"<<endl;}
           ~Derived(){ cout<<"Destructor : Derived"<<endl;}
};
void main()
{
        Base *Var = new Derived();
        delete Var;
}

Note:
There is one more point to be noted regarding virtual destructor. We can't declare pure virtual destructor. Even if a virtual destructor is declared as pure, it will have to implement an empty body (at least) for the destructor.

Don't Stop Music (just 4 fun, not 4 study :)))

Love to be love by U !

Lyrics :
I can't believe I'm standing here
Been waiting for so many years and
Today I found the queen to reign my heart.
You changed my life so patiently
And turned it into something good and real
I feel just like I felt in all my dreams
There are questions hard to answer, can't you see...

[chorus]
Baby, tell me how can I tell you
That I love you more than life?
Show me how can I show you
That I'm blinded by your light.
When you touch me, I can touch you
To find out the dream is true.

I love to be loved by you.

You're looking kinda scared right now,
You're waiting for the wedding vows.
But I don't know if my tongue's able to talk
Your beauty is just blinding me,
Like sunbeams on a summer stream
And I gotta close my eyes to protect me.
Can you take my hand and lead me from here please?

Yeah,yeah

[chorus]

I love to be loved-
I need to be loved -
I love to be loved by you.

I know they're gonna say
Our love's not strong enough tO last forever.
And I know they're gonna say that we'll give up
Because of heavy weather.
But how can they understand
That our love is just heaven-sent,
We keep on going on and on
Cause this is where we both belong.

[chorus]

I love to be loved -
I need, yes I need to be loved -
I love to be loved by you.
Yes, I love to be loved by you.



Eternal flame

lyrics :
Close your eyes
Give me your hand, Darling
Do you feel my heart beating?
Do you understand?
Do you feel the same?
Am I only dreaming?
Is this burning an eternal flame?

I believe it's meant
to be, Darling
I watch you when you are sleeping
You belong with me
Do you feel the same?
Am I only dreaming?
Or is this burning an
eternal flame?

Say my name
Sun shines through the rain
My whole life so lonely
You come and ease the pain
I don't wanna lose this feeling
Ooooh...

Say my name
Sun shines through the rain
[ Find more Lyrics on www.mp3lyrics.org/4GA ]
My whole life so lonely
You come and ease the pain
I don't wanna lose this feeling
Oooh...

Close your eyes
Give me your hand, darling
Do you feel my heart beating?
Do you understand?
Do you feel the same?
Am I only dreaming?
Or is this burning an
eternal flame?

Close your eyes
Give me your hand, Darling
Do you feel my heart beating?
Do you understand?
Do you feel the same?
Am I only dreaming?
Is this burning an eternal flame?

Close your eyes
Give me your hand
(Give me your hand)
Do you feel my heart beating?
(Do you feel, Do you
feel my heart)
Do you understand?
Do you feel the same?
Am I only dreaming?
Is this burning ..... ?

Because I love U


Lyrics
If I got down on my knees and I pleaded with you
If I crossed a million oceans just to be with you
Would you ever let me down?

If I climbed the highest mountain just to hold you tight
If I said that I would love you every single night
Would you ever let me down?

Well I'm sorry if it sounds kinda sad, it's just that
Worried, so worried
that you let me down

Chorus: Because I love you, love you
Love you, so don't let me down

If I swam the longest river just to call your name
If I said the way I feel for you would never change
Would you ever fool around

Well I'm sorry if it sounds kinda bad, just that
Worried, cuz' I'm so worried
that you let me down

Chorus

Well I'm sorry if it sounds kinda bad, just that
Worried, cuz' I'm so worried
that you let me down

Fix Error with NetBeans 6.7.1 in J2EE

C:\Documents and Settings\Administrator\My Documents\NetBeansProjects\mapper\nbproject\build-impl.xml:366: The libs.CopyLibs.classpath property is not set up.
This property must point to
org-netbeans-modules-java-j2seproject-copylibstask.jar file which is part
of NetBeans IDE installation and is usually located at
<netbeans_installation>/java<version>/ant/extra folder.
Either open the project in the IDE and make sure CopyLibs library
exists or setup the property manually. For example like this:
ant -Dlibs.CopyLibs.classpath=a/path/to/org-netbeans-modules-java-j2seproject-copylibstask.jar


Fix:
I updated the build.xml file

<target name="-init-taskdefs">
<property name="libs.CopyLibs.classpath" value="bin/copylibstask.jar"/>
<fail unless="libs.CopyLibs.classpath">
..........

And it worked.

Game Bắn tăng TankAge (BattleCity) đã xuất hiện trên di động.

Vừa viết xong :happy: Đây là Game đầu tay viết bằng J2ME ,sướng phết show lên :D :cheers: :cheers:
-50 level đánh tự động cấp đọ tăng dần
-Hỗ trợ cho người chơi tự xây dựng bản đồ theo ý mình (constructor)
-Hỗ trợ dầy đủ mọi hiệu ứng giống y như game cho điện tử 4 nút xưa kia + thêm 1 vài chức năng mới :D (đóng băng , nổ , bonus, sao, âm thanh ,tên lửa , etc...)
-Khi nào rảnh có thể cho hỗ trợ oánh qua bluetooth :D










Link :
http://files.myopera.com/ThanhBinhBlog/Code/BattleCiTy.rar

Connect to MySQL using C#

Tự dưng phải làm bài tập lớn môn nhập môn CSDL phải làm vái cái demo về CSDL.
Quyết định dùng C# và MySQL cho nó dễ
:whistle: :whistle:
Sau 1 buổi chiều đọc qua C# để làm quen ngôn ngữ ,đã đến lúc thử kết nối nó với CSDL MySQL.
1.DownLoad MýSQL connector về cài đặt tại đây :
http://dev.mysql.com/downloads/connector/net/6.2.html
2.Cài đặt bình thườngđể MySQL connector dăng kí với MS-Studio 2008.Nhớ khởi động lại MS-Studio nếu nó dang bật.
3.Khởi đọng MSStudio tab view chọn server Ẽxplorer, right click vào data connection node, chọn add connection
item, chọn MySQL--> continue.Điền đầy đủ thông tin về úser và pass là OK.
4.Giờ đã kết nối thành công ta đã có thể chỉnh sử, xóa,etc bảng và code vô tư :happy: :rolleyes:
Nhưng trước khi code nhớ import reference MySQL.Data để có thể sử dụng được các NameSpace của nó nhé
:coffee: :coffee:

Code demo :
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using MySql.Data;
using MySql.Data.MySqlClient;

namespace MysQLConnection
{
    class Program
    {
        static void Main(string[] args)
        {
            string connStr = "server=localhost;user=root;database=bookstore;port=3306;password=abcabacmaymua:);";
            MySqlConnection conn = new MySqlConnection(connStr);
            try
            {
                Console.WriteLine("Connecting to MySQL...");
                conn.Open();
                Console.WriteLine("Connection successfull !");
                // Perform databse operations
                conn.Close();
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            Console.WriteLine("Done.");

        }
    }
}

Chạy được thấy dòng chữ "connection succcess!" là OK

---------------------------Have Fun ! :cheers: :cheers: :cheers: :cheers: ----------------

Sound in J2ME Game

Viết Game cho mobile một phần không thể thiếu đó là hiệu ứng âm thanh ,trước với bản 1.0 điều này chưa thể thực hiện được thì nay với bản 2.0 thì đó là chuyện quá đơn giản.
Mọi thứ ta cần đã có sẵn trong gói javax.microedition.media.* hỗ trợ có thể chơi kha nhiều loại định dạng file
khác nhau ,nhưng 2 loại đơn giản nhất đó là wav và MIDI.Công việc nhúng nhạc vào cũng khá đơn giản .
Nếu bạn muốn làm nhạc nền thì có thể sử dụng 1 thread implements runnable ,hoặc neus đơn giản chỉ là phát ra 1 âm thanh,tiếng nổ khi 1 sự kiện gì đó xảy ra trong Game thì ta chỉ cần chho player phát 1 đoạn nhạc với 1 ssos lần lặp nhất định .Like this :
import java.io.InputStream;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.Manager;

...............
 try{
            InputStream in = getClass().getResourceAsStream("/shoting.wav");
            firePlayer = Manager.createPlayer(in,"audio/x-wav");
            firePlayer.setLoopCount(1);
            in=getClass().getResourceAsStream("/bum.wav");
            destroySound = Manager.createPlayer(in,"audio/x-wav");
            destroySound.setLoopCount(1);
            //player.start();

        } catch (MediaException ex) {
            ex.printStackTrace();
        }
.........................
      destroySound.stop();
      destroySound.start();
..........................
//khi bắn
           try {
                    firePlayer.stop();
                    firePlayer.setLoopCount(1);
                    firePlayer.start();
                }
                catch (MediaException ex) {
                    ex.printStackTrace();
                }



--------------Have fun ! & Good luck ! :coffee:-------

RecordStore in J2ME

Trong J2ME rất hạn chế về việc lưu trữ và truy xuất tài nguyên. Theo tôi được biết thì
J2ME không cho phép ghitrực tiếp lên file .Nếu bạn làm một từ điển lưu trữ dữ liệu từ file thì
chức năng update(thêm từ) không thể update trực tiếp vào file mà phải ghi vào một vùng nhớ khác.
Dữ liệu được lưu trữ bằng loại bộ nhớ giới hạn gọi là RecordStore .
Gói javax.microedition.rms.* cung cấp RecordStore la`một loại Persistent DataBase lưa trữ thông tin vĩnh viễn
trên thiết bị cho các ứng dụng midlet

Đây là một loại cơ sở dữ liệu mini giúp cho bạn có thể lưa trữ và truy xuất thông tin cho các lần chạy ứng dụng sau.
Nào chúng ta cùng đến với một demo nho nhỏ :
import javax.microedition.rms.*;
import javax.microedition.midlet.*;


/**
 * @author Administrator
 */
public class RecordMidlet extends MIDlet {
   private RecordStore rs = null;
  static final String REC_STORE = "db_1";
  public RecordMidlet(){
   openRecStore();   // Create the record store

    // Write a few records and read them back
    writeRecord("J2ME and MIDP");
    writeRecord("Wireless Technology");
    writeRecord("J2ME thật là tuyệt !");
    readRecords();

    closeRecStore();  // Close record store
    deleteRecStore(); // Remove the record store
  }

    public void startApp() {
    // There is no user interface, go ahead and shutdown
    destroyApp(false);
    notifyDestroyed();
    }

    public void pauseApp() {
    }

  public void openRecStore()
  {
    try
    {
      // The second parameter indicates that the record store
      // should be created if it does not exist
      rs = RecordStore.openRecordStore(REC_STORE, true );
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }

  public void closeRecStore()
  {
    try
    {
      rs.closeRecordStore();
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }

  public void deleteRecStore()
  {
    if (RecordStore.listRecordStores() != null)
    {
      try
      {
        RecordStore.deleteRecordStore(REC_STORE);
      }
      catch (Exception e)
      {
        db(e.toString());
      }
    }
  }

  public void writeRecord(String str)
  {
    byte[] rec = str.getBytes();

    try
    {
      rs.addRecord(rec, 0, rec.length);
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }

  public void readRecords()
  {
    try
    {
      // Intentionally make this too small to test code below
      byte[] recData = new byte[5];
      int len;

      for (int i = 1; i <= rs.getNumRecords(); i++)
      {
        if (rs.getRecordSize(i) > recData.length)
          recData = new byte[rs.getRecordSize(i)];

        len = rs.getRecord(i, recData, 0);
        System.out.println("Record #" + i + ": " + new String(recData, 0, len));
        System.out.println("------------------------------");
      }
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  //debug
  private void db(String str)
  {
    System.err.println("Msg: " + str);
  }
    public void destroyApp(boolean unconditional) {
         notifyDestroyed();
    }
}

Ở trên ta dùng lệnh openRecordStore,closeRecordStore,deleteRecordStore,addRecord,getRecord để tạo,
đóng,xóa,thêm,đọc dữ liệu từ RecordStore
Kết quả thu được sẽ là:
Running with storage root C:\Documents and Settings\Administrator\j2mewtk\2.5.2\appdb\temp.DefaultColorPhone125
Running with locale: English_United States.1252
Running in the identified_third_party security domain
Record #1: J2ME and MIDP
------------------------------
Record #2: Wireless Technology
------------------------------
Record #3: J2ME th?t là tuy?t !
------------------------------


---------------------Have fun !&& Good luck :coffee:---------------

Image Colors In Hexa Code

Trong lập trình J2Me nói riêng và lập trình đồ họa nói chung
thì việc phối màu là cực kì quam trọng .Vấn đề này không chỉ phụ
thuộc vào kĩ thuật của người lập trình mà nó còn phụ thuộc vào
óc thẩm mỹ của mỗi người :wink: .
Dưới đây là bảng mã màu(hexa) của các màu khá đầy đủ mà mình tìm thấy tren mạng.