Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 29 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
29
Dung lượng
58,94 KB
Nội dung
Chương 2 Lớp , Đ ối tượngvàtínhđónggói 38 38 Bài tập III 1. Viết chương trình thay đổilớp stack để cho nó cấp phát bộ nhớ động cho ngăn xếp chứa các ký tự. Kích thước ngăn xếp được chỉ rõ bằng một tham số với hàm tạo. Hàm hủy giải phóng bộ nhớ động. 2. Hãy tạo lớp t_and_d để truyền ngày và giờ hệ thống hiện hành như một tham số cho hàm tạo của nó khi được tạo ra. Lớp gồm có hàm thành viên hiển thò ngày giờ này lên màn hình. Dùng các hàm ngày và giờ chuẩn trong thư viện chuẩn để tìm và hiện thò ngày. 3. Viết chương trình tạo lớp box có hàm tạo được truyền 3 giá trò double, diễn tả độ dài các cạnh của hộp. Hãy cho lớp box tính thể tích của hình lập phương và lưu trữ kết qủa trong biến double. Tạo hàm thành viên vol() để hiển thò thể tích của mỗi đốitượng box. IV/ Nộituyếntựđộng(in-line) 1/ Khái niệm Khi đònh nghiã hàm thành phần là đủ ngắn thì có thể đặt đònh nghiã trong khai báo hàm trong lớp đó. Hàm này sẽ được gọi là hàm nộituyến (in-line func.) và không cần dùng từ khoá inline đứng trước hàm đó. Ví dụ 4.1 #include <iostream.h> class samp { int i, j; public: samp(int a, int b); // divisible() is defined here and automatically in-lined int divisible() { return !(i%j) ; } }; Chương 2 Lớp , Đ ối tượngvàtínhđónggói 39 39 samp::samp(int a, int b) { i = a; j = b; } int main() { samp ob1(10, 2), ob2(10, 3); // this is true if(ob1.divisible()) cout << "10 divisible by 2\n"; // this is false if(ob2.divisible()) cout << "10 divisible by 3\n"; return 0; } Ví dụ 4.2 Dùng hàm nộituyến để đònh nghiã các hàm tạo và hàm hủy #include <iostream.h> class samp { int i, j; public: samp(int a, int b) { i = a; j = b; } // inline constructor int divisible() { return !(i%j); } }; Ví dụ 4.3 Một hàm ngắn ở bên trong một khai báo lớp cho dù đặc điểm nộituyếntựđộng là không có giá trò. class myclass { int i; public: myclass(int n) { i = n; } Chương 2 Lớp , Đ ối tượngvàtínhđónggói 40 40 void show() { cout << i; } }; Bài tập IV 1. Viết chương trình chuyển đổilớp stack trong ví dụ 2.3 chương 2, để lớp này sử dụng các hàm nộituyếntựđộng ở những nơi thích hợp. 2. Viết chương trình chuyển đổilớp strtype trong ví dụ 2.4 chương 2, để lớp này sử dụng các hàm nộituyếntự động. V/ Gán đốitượng 1/ Khái niệm Một đốitượng được gán cho một đốitượng khác để cả hai đốitượng có cùng kiểu, khi đó sự sao chép từng bit của các thành viên dữ liệu được thực hiện . Ví dụ 5.1 // An example of object assignment. #include <iostream.h> class myclass { int a, b; public: void set(int i, int j) { a = i; b = j; } void show() { cout << a << ' ' << b << "\n"; } }; int main() { myclass o1, o2; o1.set(10, 4); // assign o1 to o2 Chương 2 Lớp , Đ ối tượngvàtínhđónggói 41 41 o2 = o1 ; o1.show(); o2.show(); return 0; } Nếu bổ sung các dòng lệnh sau đây vào trước dòng return 0; , kết quả sẽ ra sao ? o1.set(3, 2); o1.show(); o2.show(); 2/ Các tính chất a/ Lệnh gán đốitượng chỉ áp dụng cho các đốitượng có cùng kiểu (về mặt vật lý) và cùng tên kiểu . Ví dụ 5.2 // This program has an error. #include <iostream.h> class myclass { int a, b; public: void set(int i, int j) { a = i; b = j; } void show() { cout << a << ' ' << b << "\n"; } }; /* This class is similar to myclass but uses a different class name and thus appears as a different type to the compiler */ class yourclass { int a, b; public: void set(int i, int j) { a = i; b = j; } void show() { cout << a << ' ' << b << "\n"; } }; Chương 2 Lớp , Đ ối tượngvàtínhđónggói 42 42 int main() { myclass o1; yourclass o2; o1.set(10, 4); o2 = o1 ; // ERROR, objects not of same type name o1.show(); o2.show(); return 0; } b/ Phép gán đốitượng còn áp dụng cho các dữ liệu phức tạp như mảng, . Ví dụ 5.3 #include <iostream.h> #define SIZE 10 // Declare a stack class for characters. class stack { char stck[SIZE]; // holds the stack int tos; // index of top-of-stack public: stack(); // constructor void push(char ch); // push character on stack char pop(); // pop character from stack }; // Initialize the stack. stack::stack() { cout << "Constructing a stack\n"; tos = 0; } Chửụng 2 Lụựp , ẹ oỏi tửụùng vaứ tớnh ủoựng goựi 43 43 // Push a character. void stack::push(char ch) { if(tos==SIZE) { cout << "Stack is full\n"; return; } stck[tos] = ch; tos++; } // Pop a character. char stack::pop() { if(tos==0) { cout << "Stack is empty\n"; return 0; // return null on empty stack } tos--; return stck[tos]; } int main() { // Create two stacks that are automatically initialized. stack s1, s2; int i; s1.push('a'); s1.push('b'); s1.push('c'); // clone s1 s2 = s1 ; // now s1 and s2 are identical for(i=0; i<3; i++) cout << "Pop s1: " << s1.pop() << "\n"; for(i=0; i<3; i++) cout << "Pop s2: " << s2.pop() << "\n"; Chương 2 Lớp , Đ ối tượngvàtínhđónggói 44 44 return 0; } c/ Đối với các đốitượng có sử dụng chuổi , khi thực hiện phép gán đốitượng phải chắc chắn rằng không hủy bỏ các thông tin cần thiết trong đốitượng đó. Ví dụ 5.4 // This program contains an error. #include <iostream.h> #include <string.h> #include <stdlib.h> #include <malloc.h> class strtype { char *p; int len; public: strtype(char *ptr); ~strtype(); void show(); }; strtype::strtype(char *ptr) { len = strlen(ptr); p = (char *) malloc(len+1); if(!p) { cout << "Allocation error\n"; exit(1); } strcpy(p, ptr); } strtype::~strtype() { cout << "Freeing p\n"; Chương 2 Lớp , Đ ối tượngvàtínhđónggói 45 45 free(p); } void strtype::show() { cout << p << " - length: " << len; cout << "\n"; } int main() { strtype s1("This is a test."), s2("I like C++."); s1.show(); s2.show(); // assign s1 to s2 -- this generates an error s2 = s1; s1.show(); s2.show(); return 0; } Nguyên nhân nào gây ra lỗi ? Bài tập V 1. Tìm lỗi sai trong đoạn chương trình sau #include <iostream> class cl1 { int i, j; public: cl1(int a, int b) { i = a; j = b; } // . }; class cl2 { Chương 2 Lớp , Đ ối tượngvàtínhđónggói 46 46 int i, j; public: cl2(int a, int b) { i = a; j = b; } // . }; int main() { cl1 x(10, 20); cl2 y(0, 0); x = y; // . } 2. Viết chương trình dựa vào lớp queue trong bài tập II/ 1. chương II chứng tỏ một hàng đợi có thể được gán cho một hàng đợi khác. 3. Nếu lớp queue trong câu 2. cấp phát bộ nhớ động để giữ hàng đợi, tại sao trong trường hợp này, một hàng đợi không thể được gán cho hàng đợi khác. VI/ Truyền các đốitượng sang hàm 1/ Việc truyền các đốitượng cho hàm giống như truyền các đối số thông thường. Tham số của hàm có kiểu dữ liệu là kiểu lớp, vàđối số truyền cho hàm chính là đốitượng . Giống như các kiểu dữ liệu khác, theo ngầm đònh, tất cả các đốitượng được truyền bởi giá trò cho một hàm. Ví dụ 6.1 Truyền một đốitượng cho hàm. #include <iostream.h> class samp { int i; public: Chương 2 Lớp , Đ ối tượngvàtínhđónggói 47 47 samp(int n) { i = n; } int get_i() { return i; } }; // Return square of o.i. int sqr_it( samp o ) { return o.get_i() * o.get_i(); } int main() { samp a(10), b(2); cout << sqr_it( a ) << "\n"; cout << sqr_it( b ) << "\n"; return 0; } 2/ Do đốitượng được truyền bởi giá trò cho một hàm, có nghóa là việc sao chép từng bit của đối số được thực hiện và chính sao chép này được sử dụng bởi hàm. Do đó, những thay đổi cho đốitượng bên trong hàm không có ảnh hưởng đến sự gọiđối tượng. Ví dụ 6.2 #include <iostream.h> class samp { int i; public: samp(int n) { i = n; } void set_i(int n) { i = n; } int get_i() { return i; } }; // Set o.i to its square. This has no effect on the object used to call sqr_it(), [...]... Bản sao của đốitượng Khi truyền một đốitượng cho hàm, một bản sao của đốitượng được thực hiện, có nghóa là một đốitượng mới xuất hiện Do đó khi hàm kết thúc làm việc, bản sao của đốitượng đó (đối số của hàm) sẽ bò hủy Điều này làm nảy sinh hai vấn đề : - Hàm tạo của đốitượng được gọi khi bản sao thực hiện ? - Hàm hủy của đốitượng được gọi khi bản sao bò hủy ? Khi bản sao của một đốitượng được... Khi một đốitượng được trả về từ một hàm, một đốitượng tạm được dùng để thực hiện sự trả về sẽ làm hủy bộ nhớ (được cấp phát cho chuổi s) của đốitượng được gọi Để tránh tình trạng này có thể sử dụng hàm tạo bản sao 56 Chương 2 Lớp, Đối tượngvà tính đónggói 57 Bài tập VII 1 Viết chương trình tạo lớp Who, cho hàm tạo của Who nhận một đối số ký tự mà đối số này được dùng để nhận dạng một đốitượng Hãy... neg(dyna ob) { return -ob.get(); } int main() { dyna o (-1 0); cout . Chương 2 Lớp , Đ ối tượng và tính đóng gói 54 54 } VII/ Trả đối tượng từ hàm • Đối tượng trả về từ hàm thông qua câu lệnh return . Khi đó một đối tượng tạm. "
"; Chương 2 Lớp , Đ ối tượng và tính đóng gói 44 44 return 0; } c/ Đối với các đối tượng có sử dụng chuổi , khi thực hiện phép gán đối tượng phải chắc