Lập trình hướng đối tượng với C++
- C++ là một sựmởi rộng của C, do đó có thểsửdụng một chương trình biên dịch
C++ đểdịch và thực hiện các chương trình viết bằng C
- C yêu cầu các chú thích nằm giữa /* và */. C++ cho phép tạo một chú thích bắt đầu
bằng “//” cho đến hết dòng
- C++ cho phép khai báo tuỳý. Thậm chí có thểkhai báo biến trong phần khởi tạo
của câu lênh lặp for
- C++ cho phép truyền tham sốcho hàm bằng tham chiếu. Điều này tương tựnhư
truyền tham biến cho chương trình con trong ngôn ngữlập trình PASCAL. Trong lời gọi
hàm ta dùng tên biến và biến đó sẽ được truyền cho hàm qua tham chiếu. Điều đó cho
phép thao tác trực tiếp trên biến được truyền chứkhông phải gián tiếp qua biến trỏ.
- Toán tửnew và delete trong C++ được dùng đểquản lý bộnhớ động thay vì các
hàm cấp phát động của C
- C++ cho phép người viết chương trình mô tảcác giá trịngầm định cho các tham số
của hàm, nhờ đó hàm có thể được gọi với một danh sách các tham sốkhông đủ.
- Toán tử“::” cho phép truy nhập biến toàn cục khi đồng thời sửdụng biến cục bộvà
toàn cục cùng tên.
- Có thể định nghĩa các hàm cùng tên với các tham sốkhác nhau. Hai hàm cùng tên
sẽ được phân biệt nhờgiá trịtrảvềvà danh sách kiểu các tham số
+= S2;
cout << S1 << endl;
cout << "S1 += \" to you\" yields" << endl;
S1 += " to you";
cout << "S1 = " << S1 << endl;
cout << "The substring of S1 starting at" << endl
<< "location 0 for 14 characters, S1(0,
14), is: "
<< S1(0, 14) << endl;
cout << "The substring of S1 starting at" << endl
<< "location 15, S1(15, 0), is: "
<< S1(15, 0) <<endl; // 0 is "to end of
string"
String *S4Ptr = new String(S1);
cout << "*S4Ptr = " << *S4Ptr <<endl;
cout << "assigning *S4Ptr to *S4Ptr" << endl;
*S4Ptr = *S4Ptr;
cout << "*S4Ptr = " << *S4Ptr << endl;
delete S4Ptr;
S1[0] = 'H';
S1[6] = 'B';
cout <<"S1 after S1[0] = 'H' and S1[6] = 'B' is:
"<< S1 << endl;
cout << "Attempt to assign 'd' to S1[30] yields:"
<< endl;
S1[30] = 'd'; //Loi: Chi so vuot khoi mien!!!
return 0;
}
28.
kết quả
LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++
Trang 46
D/ BÀI TẬP TỰ GIẢI
Câu hỏi trắc nghiệm
Câu 1:
Định nghĩa nào đúng cho toán tử nhập(>>) của một lớp T
a) istream& operator>>(istream&);
b) istream& operator>>(istream);
c) friend istream& operator>>(istream&, T&);
d) friend istream& operator>>(istream&, T);
LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++
Trang 47
Câu 2
Định nghĩa nào phù hợp nhất cho toán tử lấy thành phần([]) của lớp mảng A
a) int operator [] (int)
b) int& operator [] (int)
c) friend int operator [] (A&, int)
d) friend int& operator [] (A&, int)
Câu 3:
Chỉ ra cách định nghĩa toán tử cho lớp T bị sai
a) T operator-(T&)
b) T operator-()
c) T operator-()
d) friend T opreator +(T&);
e) T operator +(T&);
Câu 4:
Chỉ ra cách định nghĩa toán tử cho lớp T bíai
a) T& operator ++()
b) T operator ++();
c) T& operator++(int);
d) T&operator++(float)
Câu 5:
Cho lớp A
class A
{
public:
operator int ();
};
A a;
int i=a;(1)
float f=a;(2)
Chỉ ra dòng nào có lỗi
a) Chỉ dòng 1 lỗi
b) Chỉ dòng 2 lỗi
c) Cả hai dòng đều lỗi
d) Không dòng nào lỗi
Bài tâp
Bài 1:
Tạo kiểu dữ liệu Date biểu diễn ngày, tháng, năm. Cài đặt các toán tử để tính một
ngày trước hoặc sau một ngày xác định nào đó, tính khoảng cách thao ngày giữa hai
ngày xác định, tính thứ trong tuần của ngày. Các toán tử
vào ra cho ngày.
Bài 2:
Để lưu trữ một ma trận đối xứng thì không cần đủ ô nhớ cho tất cả các phần tử của
nó. Xây dựng lớp biểu diễn ma trận đối xứng có các toán tử truy nhập từng phần tử của
ma trận. Chỉ sử dụng đủ lượng bộ nhớ cần thiết để lưu ma trận đối xứng
Bài 3
Xây dựng lớp biểu diễn các đa thức với các toán tử cộng, trừ, nhân, chia và đảo dấu.
Định nghĩa toán tử xuất để kết xuất.
Bài 4:
Xây dựng một lớp map cho phép biểu diễn một ánh xạ từ một chuỗi kí tự thành một
giá trị số nguyên. Định nghĩa toán tử [] cho lớp để có thể sử dụng ánh xạ theo cách như
[“abc”]->5
LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++
Trang 48
Bài 5
Xây dựng một lớp biểu diễn các vector n chiều với các toán tử cộng, trừ, tích có
hướng hai vector và tích vô hướng một vector với một số thực. Định nghĩa toán tử cho
phép truy nhập các thành phần của vector.
LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++
Trang 49
Kü thuËt thõa kÕ
MỤC TIÊU CỦA BÀI NÀY GIÚP NGƯỜI HỌC
Cài đặt được sự thừa kế
Sử dụng các thành phần của lớp cơ sở
Định nghĩa lại các hàm thành phần
Truyền thông tin giữa các hàm thiết lập của lớp dẫn xuất và lớp cơ sở
Các loại dẫn xuất khác nhau và sự thay đổi trạng thái của các thành phần lớp cơ
sở.
Sự tương thích giữa các đối tượng của lớp dẫn xuất và lớp cơ sở
Toán tử gán và thừa kế
Hàm ảo và tính đa hình
A/ NHẮC LẠI LÝ THUYẾT
Thừa kế nâng cao khả năng sử dụng lại của các đoạn mã chương trình.
Người lập trình có thể khai báo lớp mới thừa thừa kế dữ liệu và hàm thành phần từ
lớp cơ sở đã được định nghĩa trước đó. Ta gọi lớp mới là lớp dẫn xuất.
Trong đơn thừa kế, một lớp chỉ có thể có một lớp cơ sở. Trong đa thừa kế cho phép
một lớp là dẫn xuất của nhiều lớp
Lớp dẫn xuất thường bổ sung các thành phần dữ liệu và các hàm thành phần trong
định nghĩa, ta nói lớp dẫn xuất cụ thể hơn so với lớp cơ sở và vì vậy thường mô tả một
lớp các đối tượng có phạp vi hẹp hơn lớp cơ sở.
Lớp dẫn xuất không có quyền truy nhập đến các thành phần private của lớp cơ sở.
Tuy nhiên lớp cơ sở có quyền truy xuất đến các thành phần công cộng và được bảo
vệ(proteced).
Hàm thiết lập của lớp dẫn xuất thường tự động gọi các hàm thiết lập của các lớp cơ
sở để khởi tạo giá trị cho các thành phần trong lớp cơ sở.
Hàm huỷ bỏ được gọi theo thứ tự ngược lại.
Thuộc tính truy nhập protected là mức trung gian giữa thuộc tính public và private.
Chỉ có các hàm thành phần và hàm bạn của lớp cơ sở và lớp dẫn xuất có quyền truy
xuất đến các thành phần protected của lớp cơ sở.
Có thể định nghĩa lại các thành phần của lớp cơ sở trong lớp dẫn xuất khi thành đó
không còn phù hợp trong lớp dẫn xuất.
Có thể gán nội dung đối tượng lớp dẫn xuất cho một đối tượng lớp cơ sở. Một con
trỏ lớp dẫn xuất có thể chuyển đổi thành con trỏ lớp cơ sở.
Hàm ảo được khai báo với từ khoá virtual trong lớp cơ sở.
Các lớp dẫn xuất có thể đưa ra các cài đặt lại cho các hàm ảo của lớp cơ sở nếu
muốn, trái lại chúng có thể sử dụng định nghĩa đã nêu trong lớp cơ sở.
Nếu hàm ảo được gọi bằng cách tham chiếu qua tên một đối tượng thì tham chiếu
đó được xác định dựa trên lớp của đối tượng tương ứng.
Một lớp có hàm ảo không có định nghĩa(hàm ảo thuần tuý) được gọi là lớp trừu
tượng. Các lớp trừu tượng không thể dùng để khai báo các đối tượng nhưng có thể
khai báo con trỏ có kiểu lớp trừu tượng.
B. MỘT SỐ LƯU Ý (Các lỗi thường gặp, một số thói quen lập trình tốt...)
Các lỗi thường gặp
Cho con trỏ lớp dẫn xuất chỉ đến đối tượng lớp cơ sở mà không đảm bảo chắc chắn
rằng phiên bản mới của hàm trong lớp dẫn xuất cũng trả về cùng gái trị như phiên
bản cũ của hàm.
Khai báo đối tượng của lớp trừu tượng
LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++
Trang 50
Khai báo hàm thiết lập là hàm ảo.
Một số thói quen lập trình tốt
Khi thừa kế các khả năng không cần thiết trong lớp dẫn xuất, tốt nhất nên định nghĩa
lại chúng.
C/ BÀI TẬP MẪU
Ví d 1:
Giả sử có các lớp như trong khai báo. Chỉ ra các lỗi sai cho các lệnh của chương
trình viết dưới đây.
class A
{
public:
void func();
};
class B: private class A
{ };
A a;
B b;
a.func();
A* pA =&b;
B* pB=&a;
Lời giải
Lời gọi b.func() có lỗi bởi vì lớp B kế thừa lớp A theo chế độ private. Do vậy, tất cả
các thành phần của A sẽ là private trong B, hơn nữa không thể truy nhập vào một
thành phần private.
Một đối tượng của lớp dẫn xuất cũng có thể coi là đối tượng của lớp cơ sở. Do vậy,
khia báo A* pA=&b là hoàn toàn đúng. Nhưng điều ngược lại là không đúng, nên khai
báo B* pB=&a sẽ gây lỗi khi biên dịch.
Ví dụ 2: Quản lý học viên
CT4_2.CPP
#include
#include
class person_data
{
public:
void getinfo();
void display();
person_data();
virtual ~person_data();
private:
char name[25];
int roll_no;
char sex;
};
person_data::person_data()
{
}
person_data::~person_data()
{
}
void person_data::getinfo()
{
cout << "Ten: ";
29.
LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++
Trang 51
cin>> name;
cout<<"So: ";
cin>>roll_no;
cout<<"Gioi tinh(F/M) : ";
cin>> sex;
}
void person_data:: display()
{
cout<<name<<"\t";
cout<<roll_no<<"\t";
cout<<sex<<"\t";
}
//-----------------------------------
class academics
{
public:
void getinfo();
void display();
academics();
virtual ~academics();
private:
char course_name[25];
int semester;
char grade[3];
};
academics::academics()
{
}
academics::~academics()
{
}
void academics::getinfo()
{
cout<<"Ten khoa (BA/MBA/MCA etc)? ";
cin>>course_name;
cout<< "Hoc ky (1/2/3/...)? ";
cin>>semester;
cout<<"muc do (A,B,B+,B-..) ? ";
cin>>grade;
}
void academics::display()
{
cout<<course_name<<"\t";
cout<<semester<<"\t";
cout<<grade<<"\t";
}
//-------------------------------
class stud_scholarship :
public person_data,
public academics
{
public:
void getinfo();
void display();
stud_scholarship();
virtual ~stud_scholarship();
LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++
Trang 52
private:
float amount;
};
stud_scholarship::stud_scholarship()
{
}
stud_scholarship::~stud_scholarship()
{
}
void stud_scholarship::getinfo()
{
person_data::getinfo();
academics::getinfo();
cout<<"Su ho tro ";
cin>>amount;
}
void stud_scholarship::display()
{
person_data::display();
academics::display();
cout<<amount<<endl;
}
//----------------------------------
int main()
{
stud_scholarship obj;
cout<<"Nhap cac thong tin sau: "<<endl;
obj.getinfo();
cout<<endl;
cout<<"Ten So Gioi tinh Khoa Hoc ky Muc do";
cout<<" Amount"<<endl;
obj.display();
return 0;
}
30.
D/ BÀI TẬP TỰ GIẢI
Bài 1: Xây dựng lớp Stack với các thao tác cần thiết. Từ đó hãy dẫn xuất từ lớp Stack
để đổi một số nguyên dương sang hệ đếm bất kỳ.
Bài 2: Hãy xây dựng các lớp cần thiết trong phân cấp hình 5.2
Bài 3: Hãy xây dựng các lớp cần thiết trong phân cấp hình 5.3 để tính diện tích (hoặc
diện tích xung quanh) và thể tích.
Bài 4: Viết một phân cấp kế thừa cho các lớp Quadrilateral (hình tứ giác), Trapezoid
(hình thang), Parallelogram (hình bình hành), Rectangle (hình chữ nhật), và Square
(hình vuông). Trong đó Quadrilateral là lớp cơ sở của phân cấp.
File đính kèm:
Lập trình hướng đối tượng với C++.pdf

