Bài giảng Lập trình hướng đối tượng (Phần 1)

LËp tr×nh h íng ®èi t îng  
MỤC LỤC  
Chương 1: Lập trình hướng đối tượng và C++....................................................... 5  
Trang - 1 -  
 
LËp tr×nh h íng ®èi t îng  
Trang - 2 -  
LËp tr×nh h íng ®èi t îng  
Trang - 3 -  
LËp tr×nh h íng ®èi t îng  
Trang - 4 -  
LËp tr×nh h íng ®èi t îng  
Chương 1: Lập trình hướng đối tượng và C++  
Nội dung của chương tập trung trình bày các vấn đề sau:  
Lập trình hướng đối tượng là gì?  
Một số khái niệm trong lập trình hướng đối tượng.  
Giới thiệu về C++ và một số mở rộng của C++ so với C.  
Hàm trong C++.  
1.1. Lập trình hướng đối tượng là gì  
Vào những ngày đầu phát triển của máy tính, khi các phần mềm còn rất đơn giản  
chỉ cỡ vài chục dòng lệnh, chương trình được viết tuần tự với các câu lệnh được  
thực hiện từ đầu đến cuối. Cách lập trình như vậy được gọi là phương pháp lập  
trình tuyến tính. Khoa học máy tính ngày càng phát triển, các phần mềm đòi hỏi  
ngày một phức tạp và lớn hơn rất nhiều. Vì vậy, xuất hiện một phương pháp lập  
trình mới gọi là lập trình cấu trúc. Theo phương pháp này, chương trình được tổ  
chức thành các chương trình con. Mỗi chương trình con đảm nhận xử lý một công  
việc nhỏ trong toàn bộ hệ thống. Mỗi chương trình con này lại có thể chia nhỏ  
thành các chương trình con nhỏ hơn. Quá trình phân chia như vậy cứ tiếp diễn cho  
tới khi các chương trình con nhận được là đủ đơn giản để giải quyết. Người ta gọi  
quá trình đó là “làm mịn dần”. Theo quan điểm của phương pháp này: Chương  
trình = Cấu trúc dữ liệu + Giải thuật. Vì vậy, để lập được một chương trình đòi hỏi  
người lập trình phải có kiến thức vững vàng về Cấu trúc dữ liệu. Một khó khăn nữa  
gặp phải là chương trình phụ thuộc chặt chẽ vào cấu trúc dữ liệu. Do vậy, chỉ cần  
một thay đổi nhỏ ở cấu trúc dữ liệu có thể phải viết lại cả chương trình, điều này  
không thích hợp khi xây dựng một dự án phần mềm lớn. Một phương pháp lập  
trình đang được sử dụng phổ biến hiện nay đã khắc phục được nhược điểm này của  
phương pháp lập trình cấu trúc đó chính là lập trình hướng đối tượng.  
Lập trình hướng đối tượng đặt trọng tâm vào các đối tượng (dữ liệu của hệ  
thống), không cho phép dữ liệu biến động tự do trong hệ thống. Lập trình hướng  
đối tượng có những đặc điểm chủ yếu sau:  
- Tập trung vào dữ liệu thay cho các hàm  
- Chương trình được chia thành các đối tượng  
- Cấu trúc dữ liệu được thiết kế sao cho đặc tả được đối tượng  
- Các hàm thao tác trên các vùng dữ liệu của đối tượng được gắn với cấu trúc dữ  
liệu đó  
Trang - 5 -  
     
LËp tr×nh h íng ®èi t îng  
- Dữ liệu được đóng gói lại, được che dấu và không cho phép các hàm ngoại lai  
truy nhập tự do  
- Các đối tượng tác động và trao đổi thông tin với nhau qua các hàm  
- Có thể dễ dàng bổ sung dữ liệu và các hàm mới vào đối tượng nào đó khi cần  
thiết.  
1.2. Các ngôn ngữ và một vài ứng dụng hướng đối tượng  
Lập trình hướng đối tượng không phải là đặc quyền của một ngôn ngữ lập  
trình đặc biệt nào. Cũng giống như kỹ thuật lập trình có cấu trúc, các khái  
niệm trong lập trình hướng đối tượng được thể hiện trong nhiều ngôn ngữ lập  
trình khác nhau. Những ngôn ngữ cung cấp được những khả năng lập trình  
hướng đối tượng (tạo lớp, đối tượng, thừa kế,…) được gọi là ngôn ngữ lập  
trình hướng đối tượng. Một số ngôn ngữ lập trình hướng đối tượng đang dùng  
phổ biến hiện nay như: C++, Java, C#, Visual Basic.Net,..  
Lập trình là một trong những thuật ngữ được nhắc đến nhiều nhất hiện nay  
trong công nghệ phần mềm và nó được ứng dụng để phát triển phần mềm  
trong nhiều lĩnh vực khác nhau. Trong số đó, ứng dụng quan trọng và nổi  
tiếng nhất hiện nay là thiết kế giao diện với người sử dụng, kiểu như  
Windows. Các lĩnh vực ứng dụng phù hợp với kỹ thuật lập trình hướng đối  
tượng có thể liệt kê như dưới đây:  
Các hệ thống làm việc theo thời gian thực;  
Các hệ mô hình hoá hoặc mô phỏng các quá trình;  
Các hệ cơ sở dữ liệu hướng đối tượng;  
Các hệ siêu văn bản (hypertext), đa phương tiện (multimedia);  
Các hệ thống trí tuệ nhân tạo và các hệ chuyên gia;  
Các hệ thống song song và mạng nơ-ron;  
Các hệ tự động hoá văn phòng hoặc trợ giúp quyết định;  
Các hệ CAD/CAM.  
…  
1.3. Một số khái niệm trong lập trình hướng đối tượng  
1.3.1. Sự đóng gói  
Trong phương pháp lập trình cấu trúc các hàm hay thủ tục có phạm vi hoạt động  
trong toàn bộ chương trình, nó được sử dụng thông qua các lời gọi mà không cần  
Trang - 6 -  
   
LËp tr×nh h íng ®èi t îng  
biết đến nội dung cụ thể của nó. Người sử dụng chỉ cần biết chức năng của hàm  
cũng như các tham số cần truyền vào để gọi hàm chạy mà không cần quan tâm đến  
những lệnh cụ thể bên trong nó. Người ta gọi đó là sự đóng gói về chức năng.  
Trong phương pháp lập trình hướng đối tượng, không những các chức năng được  
đóng gói mà cả dữ liệu cũng như vậy. Với mỗi đối tượng người ta không thể truy  
nhập trực tiếp vào các thành phần dữ liệu của nó mà phải thông qua các thành phần  
chức năng (các phương thức) để làm việc đó.  
1.3.2. Lớp và thực thể  
Đối tượng (hay thực thể) là sự kết hợp giữa dữ liệu và thủ tục (hay còn gọi là  
phương thức - method) thao tác trên dữ liệu đó. Có thể đưa ra công thức phản ánh  
bản chất kỹ thuật của lập trình hướng đối tượng như sau:  
Đối tượng = Dữ liệu + Phương thức  
Lớp là một tập các đối tượng có cấu trúc dữ liệu và các phương thức giống nhau  
(hay nói cách khác là một tập các đối tượng cùng loại). Như vậy, khi có một lớp thì  
sẽ biết được một mô tả cấu trúc dữ liệu và phương thức của các đối tượng thuộc lớp  
đó. Mỗi đối tượng sẽ là một thể hiện cụ thể (instance) của lớp đó. Trong lập trình,  
có thể coi một lớp như là một kiểu dữ liệu, còn các đối tượng sẽ là các biến có kiểu  
của lớp.  
1.3.3. Tính thừa kế  
Tính thừa kế là khả năng cho phép định nghĩa một lớp mới trên cơ sở các lớp đã tồn  
tại, tất nhiên có bổ sung những phương thức hay các thành phần dữ liệu mới. Khả năng  
thừa kế cho phép dễ dàng chỉnh sửa và phát triển chương trình. Rõ ràng đây là một  
điểm mạnh của lập trình hướng đối tượng so với lập trình cấu trúc.  
1.3.4. Tính đa hình  
Đó là khả năng cho phép một thông điệp (lời gọi phương thức) có thể thay đổi  
cách thực hiện của nó theo lớp cụ thể của đối tượng nhận lời gọi phương thức.  
Khi một lớp dẫn xuất được tạo ra, nó có thể thay đổi cách thực hiện các phương  
thức nào đó mà nó thừa hưởng từ lớp cơ sở của nó. Một lời gọi phương thức từ đối  
tượng của lớp cơ sở, sẽ thực hiện phương thức đó trong lớp cơ sở.  
Nếu một lớp dẫn xuất định nghĩa lại một phương thức thừa hưởng từ lớp cơ sở  
của nó thì một lời gọi phương thức cùng tên với phương thức này, khi được gửi tới  
một đối tượng của lớp dẫn xuất sẽ gọi phương thức đã định nghĩa cho lớp dẫn xuất.  
Trang - 7 -  
     
LËp tr×nh h íng ®èi t îng  
1.3.5. Phương thức ảo  
C++ cũng cho phép cơ chế tương ứng bội bằng cách định nghĩa một phương  
thức là phương thức ảo trong sơ đồ thừa kế. Khi đó, một con trỏ lớp cơ sở có thể trỏ  
đến địa chỉ của một đối tượng lớp dẫn xuất, và phương thức được thực hiện là tuỳ  
thuộc vào kiểu của đối tượng mà con trỏ đang trỏ tới.  
1.4. Một số mở rộng đơn giản trong C++ so với C  
1.4.1. Môi trường C++  
C là một ngôn ngữ lập trình mạnh và linh hoạt được sử dụng rộng rãi để giải các  
bài toán khoa học kỹ thuật, ghép nối máy tính, đồ hoạ,... Để thừa kế những điểm  
mạnh vốn có của C vào năm 1983, giáo sư Bjarne Stroustrap bắt đầu nghiên cứu và  
phát triển việc cài đặt khả năng lập trình hướng đối tượng vào ngôn ngữ C tạo ra  
một ngôn ngữ mới gọi là C++. Hai dấu + trong tên gọi C++ thể hiện hai đặc điểm  
mới của C++ so với C. Đặc điểm thứ nhất là một số khả năng mở rộng so với C  
như tham chiếu, chồng hàm, tham số mặc định... Đặc điểm thứ hai chính là khả  
năng lập trình hướng đối tượng. Hiện nay C++ chưa phải là một ngôn ngữ hoàn  
toàn ổn định. Kể từ khi phiên bản đầu tiên ra đời vào năm 1986 đã có rất nhiều thay  
đổi trong các phiên bản C++ khác nhau: bản 1.1 ra đời vào năm 1986, 2.0 vào năm  
1989 và 3.0 vào năm 1991. Phiên bản 3.0 này được sử dụng để làm cơ sở cho việc  
định nghĩa một ngôn ngữ C++ chuẩn (kiểu như ANSI C).  
Trên thực tế hiện nay tất cả các chương trình dịch C++ đều tương thích với phiên  
bản 3.0. Vì vậy C++ hầu như không gây bất kỳ một khó khăn nào khi chuyển đổi từ  
một môi trường này sang môi trường khác.  
C++ chứa đựng khái niệm lớp. Một lớp bao gồm các thành phần dữ liệu bao gồm  
các thuộc tính và các phương thức( hay là hàm thành phần). Từ một lớp có thể tạo  
ra các đối tượng hoặc bằng cách khai báo thông thường một biến có kiểu là lớp đó  
hoặc bằng cách cấp phát bộ nhớ động nhờ sử dụng toán tử new. C++ cho phép  
đóng gói dữ liệu nhưng nó không bắt buộc chúng ta thực hiện điều đó. Đây là một  
nhược điểm của C++. Tuy nhiên cũng cần thấy rằng bản thân C++ chỉ là sự mở  
rộng của C nên nó không thể là một ngôn ngữ lập trình hướng đối tượng thuần  
khiết được.  
C++ cho phép định nghĩa các hàm tạo (constructor) cho một lớp. Hàm tạo là một  
phương thức đặc biệt được gọi đến tại thời điểm một đối tượng của lớp được tạo ra.  
Trang - 8 -  
     
LËp tr×nh h íng ®èi t îng  
Hàm tạo có nhiệm vụ khởi tạo một đối tượng: cấp phát bộ nhớ, gán các giá trị cho  
các thành phần dữ liệu cũng như việc chuẩn bị chỗ cho các đối tượng mới. Một lớp  
có thể có một hay nhiều hàm tạo. Để xác định hàm tạo nào cần gọi đến, chương  
trình biên dịch sẽ so sánh các đối số với các tham số truyền vào. Tương tự như hàm  
tạo, một lớp có thể có một hàm huỷ (destructor), một phương thức đặc biệt được  
gọi đến khi đối tượng được giải phóng khỏi bộ nhớ.  
Lớp trong C++ thực chất là một kiểu dữ liệu do người sử dụng định nghĩa. Khái  
niệm định nghĩa chồng toán tử cho phép định nghĩa các phép toán trên một lớp  
giống như các kiểu dữ liệu chuẩn của C. Ví dụ chúng ta có thể định nghĩa một lớp  
số phức với các phép toán cộng, trừ, nhân, chia.  
Cũng giống như C, C++ có khả năng chuyển đổi kiểu. Không những thế, C++  
còn cho phép mở rộng sự chuyển đổi này sang các kiểu do người sử dụng tự định  
nghĩa (các lớp). Ví dụ, chúng ta có thể chuyển đổi từ kiểu chuẩn int của C sang  
kiểu số phức mà ta định nghĩa chẳng hạn.  
C++ cho phép thực hiện thừa kế các lớp đã xây dựng. Từ phiên bản 2.0 trở đi,  
C++ còn cho phép một lớp thừa kế cùng một lúc từ nhiều lớp khác nhau (gọi là sự  
đa thừa kế).  
Cuối cùng C++ cung cấp những thao tác vào ra mới dựa trên cơ sở khái niệm  
luồng dữ liệu (flow). Sự ưu việt của các thao tác này ở chỗ:  
* Sử dụng đơn giản.  
* Kích thước bộ nhớ được rút gọn.  
* Khả năng áp dụng trên các kiểu do người sử dụng định nghĩa bằng cách  
sử dụng cơ chế định nghĩa chồng toán tử.  
1.4.2. Lập trình cấu trúc và lập trình hướng đối tượng  
Đặc trưng của lập trình hướng cấu trúc  
Trong lập trình hướng cấu trúc, chương trình chính được chia nhỏ thành các  
chương trình con và mỗi chương trình con thực hiện một công việc xác định.  
Chương trình chính sẽ gọi đến chương trình con theo một giải thuật, hoặc một cấu  
trúc được xác định trong chương trình chính. Các ngôn ngữ lập trình cấu trúc phổ  
biến là Pascal, C và C++. Riêng C++ ngoài việc có đặc trưng của lập trình cấu trúc  
Trang - 9 -  
 
LËp tr×nh h íng ®èi t îng  
do thừa kế từ C, còn có đặc trưng của lập trình hướng đối tượng. Cho nên C++ còn  
được gọi là ngôn ngữ lập trình nửa cấu trúc, nửa hướng đối tượng.  
Đặc trưng cơ bản nhất của lập trình cấu trúc thể hiện ở mối quan hệ:  
Chương trình = Cấu trúc dữ liệu + Giải thuật  
Cấu trúc dữ liệu là cách tổ chức dữ liệu cho việc xử lý bởi một hay nhiều chương  
trình nào đó. Giải thuật là một quy trình để thực hiện một công việc xác định.  
Trong chương trình, giải thuật có quan hệ phụ thuộc vào cấu trúc dữ liệu: Một cấu  
trúc dữ liệu chỉ phù hợp với một số hạn chế các giải thuật. Nếu thay đổi cấu trúc dữ  
liệu thì phải thay đổi giải thuật cho phù hợp. Một giải thuật thường phải đi kèm với  
một cấu trúc dữ liệu nhất định.  
Tính chất  
Mỗi chương trình con có thể được gọi thực hiện nhiều lần trong một chương  
trình chính.  
Các chương trình con có thể được gọi đến để thực hiện theo một thứ tự bất kì,  
tuỳ thuộc vào giải thuật trong chương trình chính mà không phụ thuộc vào thứ tự  
khai báo của các chương trình con.  
Các ngôn ngữ lập trình cấu trúc cung cấp một số cấu trúc lệnh điều khiển chương  
trình.  
Ưu điểm  
Chương trình sáng sủa, dễ hiểu, dễ theo dõi.  
Tư duy giải thuật rõ ràng.  
Nhược điểm  
Lập trình cấu trúc không hỗ trợ mạnh việc sử dụng lại mã nguồn: Giải thuật  
luôn phụ thuộc chặt chẽ vào cấu trúc dữ liệu. Do đó, khi thay đổi cấu trúc dữ  
liệu, phải thay đổi giải thuật, nghĩa là phải viết lại chương trình.  
Không phù hợp với các phần mềm lớn: tư duy cấu trúc với các giải thuật chỉ  
phù hợp với các bài toán nhỏ, nằm trong phạm vi một module của chương  
trình. Với dự án phần mềm lớn, lập trình cấu trúc tỏ ra không hiệu quả trong  
việc giải quyết mối quan hệ vĩ mô giữa các module của phần mềm.  
Đặc trưng của lập trình hướng đối tượng  
Trong lập trình hướng đối tượng:  
Ta coi các thực thể trong chương trình là các đối tượng và sau đó trừu tượng hoá  
đối tượng thành lớp đối tượng.  
Trang - 10 -  
LËp tr×nh h íng ®èi t îng  
Dữ liệu được tổ chức thành các thuộc tính của lớp. Nguời ta ngăn chặn việc thay  
đổi tuỳ tiện dữ liệu trong chương trình bằng các cách giới hạn truy nhập như chỉ  
cho phép truy nhập dữ liệu thông qua đối tượng, thông qua các phương thức mà đối  
tượng được cung cấp…  
Quan hệ giữa các đối tượng là quan hệ ngang hàng hoặc quan hệ thừa kế: Nếu  
lớp B thừa kế từ lớp A thì A được gọi là lớp cơ sở và B được gọi là lớp dẫn xuất.  
Lập trình hướng đối tượng có hai đặc trưng cơ bản:  
Đóng gói dữ liệu: dữ liệu luôn được tổ chức thành các thuộc tính của lớp  
đối tượng. Việc truy nhập đến dữ liệu phải thông qua các phương thức của  
đối tượng lớp.  
Sử dụng lại mã nguồn: việc sử dụng lại mã nguồn được thể hiện thông qua  
cơ chế thừa kế. Cơ chế này cho phép các lớp đối tượng có thể thừa kế từ  
các lớp đối tượng khác. Khi đó, trong các lớp dẫn xuất, có thể sử dụng các  
phương thức (mã nguồn) của các lớp cơ sở mà không cần phải định nghĩa  
lại.  
Lập trình hướng đối tượng có một số ưu điểm nổi bật:  
Không còn nguy cơ dữ liệu bị thay đổi tự do trong chương trình vì dữ liệu  
đã được đóng gói vào các đối tượng. Nếu muốn truy nhập vào dữ liệu phải  
thông qua các phương thức được cho phép của đối tượng.  
Khi thay đổi cấu trúc dữ liệu của một đối tượng, không cần thay đổi mã  
nguồn của các đối tượng khác, mà chỉ cần thay đổi một số thành phần của  
đối tượng dẫn xuất. Điều này hạn chế sự ảnh hưởng xấu của việc thay đổi  
dữ liệu đến các đối tượng khác trong chương trình.  
Có thể sử dụng lại mã nguồn, tiết kiệm tài nguyên, chi phí thời gian vì  
nguyên tắc thừa kế cho phép các lớp dẫn xuất sử dụng các phương thức từ  
lớp cơ sở như những phương thức của chính nó, mà không cần thiết phải  
định nghĩa lại.  
Phù hợp với các dự án phần mềm lớn, phức tạp.  
1.4.3. Cách viết dòng ghi chú  
Trong một chương trình cần thiết có các lời chú thích, ngoài cách viết các lời chú  
thích như trong C, trong C++ ta sử dụng // để viết lời chú thích trên một dòng. Mọi  
Trang - 11 -  
 
LËp tr×nh h íng ®èi t îng  
ký hiệu đi sau “//” cho đến hết dòng được coi là chú thích, được chương trình dịch  
bỏ qua khi biên dịch chương trình.  
Ví dụ:  
cin>>n; //nhap gia tri cho n tu ban phim  
1.4.4. Khai báo linh hoạt và hằng có kiểu  
Trong C++ không nhất thiết phải nhóm lên đầu các khai báo đặt bên trong một  
hàm hay một khối lệnh, mà có thể đặt xen kẽ với các lệnh xử lý.  
Ví dụ 1.1:  
#include<iostream.h>  
#include<conio.h>  
void main()  
{
int x,y;  
cout<<”Nhap so thu nhat:”;  
cin>>x;  
cout<<”Nhap so thu hai:”  
cin>>y;  
int tong ;  
tong = x+y;  
cout<<”Tong hai so la:”<<tong;  
getch();  
}
thËm chÝ ta cã thÓ khai b¸o biÕn trong c¸c khèi lÖnh if, for, while. Ch¼ng h¹n nh :  
for(int i = 1 ; i <= n ; i++)  
§Ó t¹o mét h»ng cã kiÓu sö dông tõ kho¸ const ®Æt tr íc mét khai b¸o cã khëi  
g¸n gi¸ trÞ.  
VÝ dô 1.2:  
const int max= 100;  
struct Diem  
{
int x,y;  
};  
const Diem d = {10, 10};  
Trang - 12 -  
 
LËp tr×nh h íng ®èi t îng  
1.4.5. C¸c kiÓu char vµ int  
Trong C mét h»ng ký tù ® îc xem lµ nguyªn do ®ã nã cã kÝch th íc b»ng 2 byte.  
Cßn trong C++ mét h»ng ký tù ® îc xem lµ gi¸ trÞ kiÓu char vµ cã kÝch th íc b»ng  
mét byte. Nh vËy, trong C++ th× sizeof(„A‟) = sizeof(char) = 1  
1.4.6. LÊy ®Þa chØ c¸c phÇn tö m¶ng thùc hai chiÒu  
Ng«n ng÷ lËp tr×nh C kh«ng cho phÐp dïng to¸n tö & ®Ó lÊy ®Þa chØ phÇn tö  
m¶ng thùc hai chiÒu. V× vËy, khi nhËp gi¸ trÞ cho phÇn tö m¶ng thùc hai chiÒu ph¶i  
sö dông mét biÕn phô cã kiÓu thùc. Tr íc tiªn ta nhËp gi¸ trÞ cho biÕn phô, sau ®ã,  
ta lÊy gi¸ trÞ biÕn phô ®ã ®Ó g¸n cho phÇn tö m¶ng thùc cÇn nhËp.  
VÝ dô 1.3:  
trong C ta viÕt:  
void nhap(float A[20][20], int n)  
{
float x;  
for(int i = 0; i < n; i++)  
for(int j = 0; j < n; j++)  
{
printf(“A[%d][%d] = “,i+1, j+1)  
scanf(“%f”, &x);  
A[i,j] = x;  
}
}
C++ cho phÐp lÊy ®Þa chØ m¶ng thùc hai chiÒu sö dông to¸n tö &. V× vËy, cã thÓ  
dïng scanf ®Ó nhËp trùc tiÕp vµo c¸c phÇn tö m¶ng.  
void nhap(float A[20][20], int n)  
{
for(int i = 0; i < n; i++)  
for(int j = 0; j < n; j++)  
{
printf(“A[%d][%d] = “,i+1, j+1)  
scanf(“%f”, &A[i,j]);  
}
}
Trang - 13 -  
   
LËp tr×nh h íng ®èi t îng  
1.4.7.Vào ra trong C++  
Các hàm vào/ra của C đều có thể sử dụng trong C++. Để sử dụng các hàm này  
chúng ta chỉ cần khai báo tệp tiêu đề stdio.h trong đó có chứa khai báo hàm nguyên  
mẫu của chúng. Bên cạnh đó, C++ còn cài đặt thêm các khả năng vào/ra mới dựa  
trên hai toán tử “>>”(nhập) và “<<” (xuất) với các đặc tính sau đây:  
- Đơn giản trong sử dụng  
- Có khả năng mở rộng đối với các kiểu mới theo nhu cầu của người lập trình.  
Trong tệp tiêu đề iostream.h người ta định nghĩa hai đối tượng cin và cout tương  
ứng với hai thiết bị chuẩn vào/ra được sử dụng cùng với “>>” và “<<”. Thông  
thường ta hiểu cout là màn hình còn cin là bàn phím.  
Cú pháp của cout:  
cout<<biểu_thức_1<<biểu_thức_2<<…<<biểu_thức_n ;  
trong đó các biểu thức có thể có kiểu là các kiểu dữ liệu như : char, int, float,  
double, xâu ký tự.  
cout<<” \n” ; dùng để xuống hàng và đưa con trỏ về đầu hàng  
Nếu như cout dùng để hiển thị dữ liệu ra màn hình thì cin dùng để nhập dữ liệu  
từ bàn phím. Có thể sử dụng cin và toán tử “>>” để nhập dữ liệu cho các biến có  
kiểu char, int, float, double và char * như sau:  
cin>>biến_1>>biến_2>>…>>biến_n;  
Ví dụ 1.4:  
Chương trình sau nhập vào 2 số nguyên và in ra màn hình tổng của hai số đó  
#include<iostream.h>  
#include<conio.h>  
void main()  
{
int so1,so2;  
cout<<”Nhap so thu nhat:”;  
cin>>so1;  
cout<<”Nhap so thu hai:”  
cin>>so2;  
cout<<”Tong hai so la:”<<so1+so2;  
getch();  
}
Trang - 14 -  
 
LËp tr×nh h íng ®èi t îng  
1.4.8. Cấu trúc trong C++  
C++ vẫn chấp nhận khai báo kiểu cấu trúc như trong C. Ngoài ra, C++ còn cho  
phép khai báo kiểu cấu trúc theo cú pháp:  
struct tên_kiểu  
{
KiÓu_dl Tr êng_1;  
KiÓu_dl Tr êng_1;  
KiÓu_dl Tr êng_1;  
} ;  
mµ kh«ng cÇn ph¶i sö dông tõ kho¸ typedef nh trong C.  
VÝ dô 1.5:  
struct product  
{
int weight;  
float price;  
} ;  
product apple;  
product banana, melon;  
1.4.9. Cấp phát bộ nhớ trong C++  
Ngoài các hàm cấp phát bộ nhớ như malloc, realloc, calloc như trong C, C++  
cung cấp toán tử new để cấp phát bộ nhớ và toán tử delete để giải phóng bộ nhớ  
được cấp phát bởi toán tử new.  
Toán tử new thay thế cho hàm malloc() hay calloc() của C, có cú pháp như sau:  
new Kiểu_dữ_liệu  
Nếu kiểu dữ liệu mô tả phức tạp, nó có thể được đặt bên trong các dấu ngoặc.  
Nếu toán tử new cấp phát không thành công thì nó sẽ trả về giá trị NULL.  
Chúng ta có thể vừa cấp phát vừa khởi động như sau :  
Con_trỏ = new Kiểu_dl(Giá_trị);  
Ví dụ 1.6:  
int *P;  
P = new int(100);  
Toán tử delete thay thế hàm free() của C, nó có cú pháp như sau :  
delete Con_trỏ;  
Trang - 15 -  
   
LËp tr×nh h íng ®èi t îng  
delete [] Con_trỏ;  
Để cấp phát một mảng, chúng ta làm như sau :  
Con_trỏ = new Kiểu_dữ_liệu[Kích_thước_mảng] ;  
Ví dụ 1.7:  
int *P;  
P = new int[10]; //Cấp phát mảng 10 số nguyên  
Chú ý: Đối với việc cấp phát mảng chúng ta không thể vừa cấp phát vừa khởi gán  
giá trị cho chúng, chẳng hạn đoạn chương trình sau là sai :  
int *P;  
P = new (int[10])(3); //Sai !!!  
Ví dụ 1.8:  
Sử dụng kiểu cấu trúc, các toán tử new, delete trong việc cài đặt một số phép  
toán trên danh sách nối kép.  
#include<iostream.h>  
#include<conio.h>  
struct node //khai bao cau truc mot nut trong ds noi kep  
{
int info;  
node *lptr;  
node *rptr;  
};  
node *l,*r;  
void create(int n)//t¹o lËp danh s¸ch nèi kÐp l u tr÷ n sè nguyªn  
{
node *p;int x;  
for(int i=1;i<=n;i++)  
{
p=new node;  
p->lptr=NULL;  
p->rptr=NULL;  
cout<<"Nhap so nguyen:";cin>>p->info;  
if(l==NULL) l=r=p;  
else  
{
Trang - 16 -  
LËp tr×nh h íng ®èi t îng  
r->rptr=p;  
p->lptr=r;  
r=p;  
}
}
}
void ht()//hiÓn thÞ c¸c sè nguyªn trong danh s¸ch  
{
node *p;  
p=l;  
while(p!=NULL)  
{
cout<<p->info<<" ";  
p=p->rptr;  
}
}
node *tim(int x)//t×m ®Þa chØ nót cã info = x cho tr íc  
{
node *p;  
p=l;  
while((p!=NULL)&&(p->info!=x))  
p=p->rptr;  
return p;  
}
void insert(node *m,int x) //bæ sung nót cã info = x vµo tr íc nót trá bëi m trong  
ds  
{
node *p;  
p=new node;  
p->info=x;  
p->lptr=NULL;  
p->rptr=NULL;  
if((r ==NULL)&&(l==NULL))l=r=p;  
else  
if(l==m) {p->rptr=m;m->lptr=p; l=p;}  
Trang - 17 -  
LËp tr×nh h íng ®èi t îng  
else  
{
p->rptr=m;  
p->lptr=m->lptr;  
(m->lptr)->rptr=p;  
m->lptr=p;  
}
}
void del(int x)//xo¸ khái danh s¸ch nót cã info = x (nÕu cã)  
{
node *p;  
p=tim(x);  
if(p!=NULL)  
{
if(l==r) l=r=NULL;  
else  
if(l==p) { l=p->rptr; l->lptr=NULL;}  
else  
if (r==p) {r=p->lptr;r->rptr=NULL;}  
else  
{
(p->lptr)->rptr=p->rptr;  
(p->rptr)->lptr=p->lptr;  
}
delete p;  
}
}
void main()  
{
int x,n;  
char tl;  
node *p;  
cout<<"n=";cin>>n;  
create(n);  
cout<<"Danh sach vua nhap\n";  
Trang - 18 -  
LËp tr×nh h íng ®èi t îng  
ht();  
do  
{
cout<<"nut tro boi m co info=";cin>>x;  
p=tim(x);  
cout<<"bo sung x=";cin>>x;  
insert(p,x);  
cout<<"\nDanh sach sau khi bo sung\n";  
ht();  
cout<<"loai bo x=";cin>>x;  
del(x);  
cout<<"Danh sach sau khi loai bo\n";  
ht();  
cout<<"Tiep tuc? c/k";cin>>tl;  
}
while(tl!='k');  
getch();  
}
1.5. Hàm trong C++  
1.5.1. Biến tham chiếu  
Biến tham chiếu là biến có đặc điểm:  
- Không được cấp phát bộ nhớ, không có địa chỉ riêng;  
- Dùng làm bí danh cho một biến nào đó và sử dụng vùng bộ nhớ của biến này.  
Để khai báo biến tham chiếu ta sử dụng cú pháp:  
Kiểu_dữ_liệu  
&Biến_tham_chiếu = Biến_được_tham_chiếu;  
Trong đó, biến được tham chiếu có thể là một phần tử mảng, hoặc một biến nhớ  
nhưng nó phải là một biến cụ thể đã tồn tại.  
Ví dụ 1.9:  
float u,v, &r = u;  
Trong ví dụ này, r là biến tham chiếu, biến được tham chiếu là biến u, hay r là bí  
danh của u. Khi đó câu lệnh: r = r +1 sẽ tăng giá trị của biến u lên 1.  
Trang - 19 -  
   
LËp tr×nh h íng ®èi t îng  
1.5.2. Truyền giá trị cho hàm theo biến tham chiếu  
Trong C++ khi dùng đối số là biến tham chiếu sẽ làm cho hàm thao tác trực tiếp  
trên vùng nhớ của các tham số do đó sẽ dễ dàng thay đổi giá trị của các tham số khi  
cần.  
Ví dụ 1.10:  
void swap(int &x, int &y)  
{ int temp = x; x = y; y = temp}  
Hàm swap đã sử dụng hai đối x, y là các biến tham chiếu. Khi đó, hàm có thể  
làm thay đổi giá trị của tham số thực được truyền cho hàm.  
Việc truyền tham số cho hàm sử dụng biến tham chiếu giống như việc truyền  
tham số sử dụng biến nhớ thông thường khác. Ví dụ, để gọi hàm swap ta viết:  
swap(a, b);  
1.5.3. Hàm trả về các tham chiếu  
Hàm có thể trả về giá trị tham chiếu hoặc có kiểu tham chiếu. Khi đó, có thể  
dùng hàm để truy nhập đến một biến hoặc một phần tử mảng nào đó.  
Định nghĩa của hàm có giá trị trả về là tham chiếu có dạng như sau:  
<type> & fct( ...)  
{
...  
return <biến toàn cục>;  
}
Trong trường hợp này biểu thức được trả lại trong câu lệnh return phải là tên của  
một biến xác định từ bên ngoài hàm, bởi vì chỉ khi đó mới có thể sử dụng được giá  
trị của hàm. Khi trả về một tham chiếu đến một biến cục bộ khai báo bên trong  
hàm, biến cục bộ này sẽ bị mất đi khi kết thúc thực hiện hàm và do vậy, tham chiếu  
của hàm cũng không còn có ý nghĩa nữa.  
Khi giá trị trả về của hàm là tham chiếu, ta có thể gặp các câu lệnh gán “kỳ dị”  
trong đó vế trái là một lời gọi hàm chứ không phải là tên của một biến. Điều này  
hoàn toàn hợp lý, bởi lẽ bản thân hàm đó có giá trị trả về là một tham chiếu. Nói  
cách khác, vế trái của lệnh gán (biểu thức gán) có thể là lời gọi đến một hàm có giá  
trị trả về là một tham chiếu.  
Ví dụ 1.11:  
Trang - 20 -  
   
Tải về để xem bản đầy đủ
pdf 87 trang yennguyen 23320 Free
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình hướng đối tượng (Phần 1)", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

File đính kèm:

  • pdfbai_giang_lap_trinh_huong_doi_tuong_phan_1.pdf