1. Trang chủ
  2. » Luận Văn - Báo Cáo

Btlt group w09 10 bộ môn phương pháp lập trình hướng Đối tượng 0

19 0 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 19
Dung lượng 1,3 MB

Nội dung

Có 2 loại Exception:  Đồng bộ: Ngoại lệ xảy ra khi có sự cố xảy ra do lỗi trong dữ liệu đầu vào hoặc khi chương trình không được trang bị để xử lý loại dữ liệu hiện tại mà nó đang làm

Trang 1

BỘ GIÁO DỤC & ĐÀO TẠO TRƯỜNG ĐẠI HỌC KHOA HỌC TỰ NHIÊN, ĐHQG-HCM

KHOA CÔNG NGHỆ THÔNG TIN



BTLT-Group-W09-10

Bộ môn: Phương pháp lập trình hướng đối tượng

Mã lớp: CQ2022/5

GVHD:Hồ Tuấn Thanh

Tên nhóm: See2plus

Thành viên:

Nguyễn Đăng Trí MSSV: 22120383

Nguyễn Văn Tý MSSV: 22120419

Phạm Tuấn Anh MSSV: 22120452

Thành phố Hồ Chí Minh, ngày 14 tháng 05 năm 2024

Trang 2

GVHD: Hồ Tuấn Thanh BTLT-Group-W09-10

Mục lục

SECTION 1: Phân công nhiệm vụ và đánh giá mức độ hoàn thành 1

SECTION 2: Nội dung bài làm 2

1 (2đ) Tìm hiểu về exception handling trong C++ Cho ví dụ minh họa 2

2 (2đ) Tìm hiểu ít nhất 5 class trong std:exception Cho ví dụ minh họa 5

3 (2đ) Tìm hiểu nguyên lý L trong SOLID principles Cho ví dụ minh họa thực tế .11

4 (2đ) Tìm hiểu nguyên lý I trong SOLID principles Cho ví dụ minh họa thực tế .14

5 (2đ) Tìm hiểu nguyên lý D trong SOLID principles Cho ví dụ minh họa thực tế .16

SECTION 3: Danh mục tài liệu tham khảo 17

Trang 3

1

GVHD: Hồ Tuấn Thanh

SECTION 1: Phân công nhiệm vụ và đánh giá mức độ hoàn thành

1 (2đ) Tìm hiểu về exception handling

trong C++ Cho ví dụ minh họa

2 (2đ) Tìm hiểu ít nhất 5 class trong

std:exception Cho ví dụ minh họa

3 (2đ) Tìm hiểu nguyên lý L trong SOLID

principles Cho ví dụ minh họa thực

tế

4 (2đ) Tìm hiểu nguyên lý I trong SOLID

principles Cho ví dụ minh họa thực

tế

5 (2đ) Tìm hiểu nguyên lý D trong SOLID

principles Cho ví dụ minh họa thực

tế

Phân công nhiệm vụ, giám sát,

kiểm tra quá trình làm bài của các

thành viên trong nhóm Kiểm tra

bài làm, tổng hợp bài làm và viết

báo cáo

Trang 4

BTLT-Group-W09-10 GVHD: Hồ Tuấn Thanh

SECTION 2: Nội dung bài làm

1 (2đ) Tìm hiểu về exception handling trong C++ Cho ví dụ minh họa.

Exception handling là gì?

Exception handling trong C++ là một cơ chế cho phép xử lý các tình huống ngoại lệ trong quá trình thực thi chương trình Khi một tình huống ngoại lệ xảy ra, chương trình sẽ nhảy đến các khối mã được xác định trước, được gọi là các khối "catch", để xử lý tình huống đó Điều này giúp chương trình có thể kiểm soát và xử lý các tình huống không mong muốn mà không cần phải dừng hoàn toàn hoặc crash

2 loại Exception:

 Đồng bộ: Ngoại lệ xảy ra khi có sự cố xảy ra do lỗi trong dữ liệu đầu vào hoặc khi chương trình không được trang bị để xử lý loại dữ liệu hiện tại mà nó đang làm việc, chẳng hạn như chia số cho không

 Không đồng bộ: Các ngoại lệ nằm ngoài tầm kiểm soát của chương trình, chẳng hạn như lỗi đĩa, ngắt bàn phím, v.v

C++ try and catch.

C++ cung cấp một tính năng sẵn có cho Xử lý ngoại lệ Nó có thể được thực hiện bằng cách sử dụng các từ khóa chuyên ngành sau: “try”, “catch” và “throw” với mỗi từ khóa có một mục đích khác nhau

 “Try” trong C++: đại diện cho một khối mã có thể ném một ngoại lệ được đặt bên trong khối thử Tiếp theo là một hoặc nhiều khối bắt Nếu một ngoại lệ xảy

ra, hãy thử chặn ném ngoại lệ đó

 “Catch” trong C++: đại diện cho một khối mã được thực thi khi một ngoại lệ

cụ thể được ném ra khỏi khối thử Mã để xử lý ngoại lệ được viết bên trong khối bắt

 “Throw” trong C++: Được sử dụng để ném một ngoại lệ Cũng được sử dụng

để liệt kê các trường hợp ngoại lệ mà một hàm ném ra, nhưng không xử lý chính nó

Trang 5

#include <iostream>

#include <stdexcept>

using namespace std;

void process(int x)

{

throw runtime_error( Divide by zero exception");

else if (x < )0

throw out_of_range( Negative value exception");

else if (x > 100)

throw overflow_error( Value too large exception");

else

/

3

Ưu

điểm:

 Tách mã xử lý lỗi khỏi mã thông thường: Trong các mã xử lý lỗi truyền thống, luôn có các điều kiện khác để xử lý lỗi Các điều kiện này và mã để xử lý lỗi được trộn lẫn với luồng bình thường Điều này làm cho mã ít đọc và có thể duy trì Với các khối try - catch, mã để xử lý lỗi trở nên tách biệt với luồng thông thường

 Function / methods có thể xử lý bất kỳ ngoại lệ nào họ chọn: Một hàm có thể đưa ra nhiều ngoại lệ, nhưng có thể chọn xử lý một số ngoại lệ Các ngoại lệ khác được ném, nhưng không bắt được có thể được xử lý bởi người gọi Nếu người gọi chọn không bắt chúng, thì các ngoại lệ được xử lý bởi người gọi của người gọi Trong C++, một function có thể chỉ định các ngoại lệ mà nó ném bằng cách sử dụng từ khóa throw Người gọi hàm này phải xử lý ngoại lệ theo một cách nào đó (bằng cách chỉ định lại hoặc bắt nó)

 Nhóm các loại lỗi: Trong C++, cả loại và đối tượng cơ bản đều có thể được ném thành ngoại lệ Chúng ta có thể tạo một hệ thống phân cấp của các đối tượng ngoại lệ, ngoại lệ nhóm trong không gian tên hoặc lớp, phân loại chúng theo các loại

dụ:

Trang 6

BTLT-Group-W09-10 GVHD: Hồ Tuấn Thanh

Trong ví dụ này, hàm process kiểm tra nhiều điều kiện khác nhau để sinh ra các loại ngoại lệ khác nhau Trong hàm main(), chúng ta sử dụng một khối try-catch để bắt các loại ngoại lệ được sinh ra bởi hàm process Các loại ngoại lệ cụ thể như runtime_error out_of_range, , và overflow_error đều là các lớp con của lớp cơ

sở exception, vì vậy chúng ta có thể bắt chúng bằng cách sử dụng một khối catch đa dạng

Ngoài ra, chúng ta cũng có một khối catch cuối cùng mà không có thông tin về loại ngoại lệ cụ thể (catch ( )), điều này đảm bảo rằng bất kỳ ngoại lệ nào không được xác định trước cũng sẽ được bắt và xử lý

}

int main() {

try {

process(0);

//Các test case khác

//process(-1);

//process(101);

//process(10);

}

catch (const exception& ) {e

cerr << "Exception caught: " << e.what() << endl;

}

catch ( ) {

cerr << "Unknown exception caught" << endl;

}

return 0;

}

Trang 7

BTLT-Group-W09-10 GVHD: Hồ Tuấn Thanh

5

Kết

quả khi hàm process truyền số 0:

2 (2đ) Tìm hiểu ít nhất 5 class trong std:exception Cho ví dụ minh họa.

2.1 class logic_error

Xác định một loại đối tượng được ném ra như một ngoại lệ Nó báo cáo các lỗi là hậu quả của lỗi logic trong chương trình, chẳng hạn như vi phạm các điều kiện tiên quyết logic hoặc bất biến lớp và có thể phòng ngừa được

Member Functions:

 Constructor: khởi tạo 1 logic_error object với thông báo đã có

 Operator=: Thay thế logic_error object

Trang 8

#include < iostream >

#include < exception >

#include < vector >

using namespace std ;

int main ()

{

try

{

vector string < > students = { " Hoc " " , Tu " " , Tri " };

string myName = students at ( 5 ); // Hàm at() sẽ ném ra một logic_error nếu chỉ số ngoài giới hạn

cout << " My name: " << myName << endl ;

}

catch (const std :: logic_error & e )

{

cerr << " Caught a logic error: " << e what () << endl ;

}

}

dụ:

Output:

2.2 class bad_typeid

Một ngoại lệ của loại này được đưa ra khi toán tử typeid được áp dụng cho giá trị con trỏ null được tham chiếu của loại đa hình

Member Functions:

 Constructor: khởi tạo 1 bad_typeid mới

 operator=: thay thế bad_typeid

 what: trả về chuỗi giải thích

Trang 9

BTLT-Group-W09-10 GVHD: Hồ Tuấn Thanh

7

dụ:

#include < iostream >

#include < exception >

#include < vector >

using namespace std ;

class A

{

public:

virtual void print ()

{

cout << " A " << endl ;

}

};

class B : public A

{

public:

void print ()

{

cout << " B " << endl ;

}

};

int main ()

{

A * ptr = nullptr;

try

{

cout << typeid(* ptr ) name () << endl ;

}

catch (const std :: bad_typeid & e )

{

cerr << " Caught a logic error: " << e what () << endl ;

}

}

Trang 10

#include < iostream >

#include

< exception > using

namespace std ; class

Base

{

public:

virtual ~Base () {}

};

class Derived : public Base

{

};

class AnotherClass : public Base

{

Output:

2.3 class bad_cast

Một ngoại lệ của loại này được ném ra khi dynamic_cast với một loại tham chiếu không thành công trong thời gian chạy và cả từ std::use_facet nếu khía cạnh được yêu cầu không tồn tại trong ngôn ngữ

Member Functions:

 Constructor: Hàm khởi tạo một bad_cast object

 operator=: Hàm thay thế một bad_cast object

 what: trả về chuỗi giải thích

dụ:

Trang 11

BTLT-Group-W09-10 GVHD: Hồ Tuấn Thanh

9

Output:

2.4 class bad_alloc

std::bad_alloc là loại đối tượng được các hàm phân bổ đưa ra dưới dạng ngoại lệ để báo cáo lỗi phân bổ bộ nhớ

Member Functions:

 Constructor: Hàm khởi tạo một bad_alloc object

 operator=: Hàm thay thế một bad_alloc object

 what: trả về chuỗi giải thích

void testDynamicCast ( Base & base )

{

try

{

// lỗi khi cố gắng ép kiểu base sang kiểu derived

Derived & derived = dynamic_cast< Derived &>(base);

std :: cout << " Dynamic cast to Derived succeeded " << std :: endl ;

}

catch (const std :: bad_cast & e )

{

std :: cerr << " Caught a bad_cast exception: " << e what () << std :: endl ; }

}

int main ()

{

AnotherClass anotherObject ;

testDynamicCast ( anotherObject );

return 0 ;

}

Trang 12

#include < iostream >

#include < exception >

int main ()

{

try

{

// Kích thước rất lớn, có thể gây ra lỗi cấp phát

size_t largeSize = static_cast< size_t >(- 1 );

int * largeArray = new int[ largeSize ];

largeArray [ 0 ] = 1 ;

std :: cout << largeArray [ 0 ];

delete[] largeArray ;

}

catch (const std :: bad_alloc & e )

{

std :: cerr << " Caught a bad_alloc exception: " << e what () << std :: endl ; }

return 0 ;

}

dụ:

Output:

2.5 class invalid_argument.

Xác định một loại đối tượng được ném ra như một ngoại lệ Nó báo lỗi phát sinh do giá trị đối số chưa được chấp nhận Ngoại lệ này được ném ra bởi std::bitset::bitset và các

họ hàm std::stoi và std::stof

Trang 13

#include < iostream >

#include < exception >

#include < string >

using namespace std ;

int main ()

{

try

{

int num = stoi ( ABCD " );

cout << num << endl ;

}

catch ( invalid_argument const & ex )

{

cout << " Exception: " << ex what () << endl ;

}

}

11

Member Functions:

 Constructor: Hàm khởi tạo một bad_alloc object

 operator=: Hàm thay thế một bad_alloc object

 what: trả về chuỗi giải thích

dụ:

Output:

3 (2đ) Tìm hiểu nguyên lý L trong SOLID principles Cho ví dụ minh họa thực tế.

Nguyên lý L trong SOLID principles là nguyên lý thay thế Liskov (Liskov Substitution Principle - LSP) Nội dung của nguyên lý như sau: “ Trong một chương trình, các object của class con có thể thay thế class cha mà không làm thay đổi tính đúng đắn của chương trình”

Trang 14

class Payment

{

public:

virtual void pay(float money) = 0;

};

class CreditCardPayment : public Payment

{

public:

void pay(float money)

{

std::cout << "Processing credit card payment of " << money << std::endl;

}

};

LSP yêu cầu rằng các lớp con phải duy trì hành vi của lớp cha Điều này có nghĩa là nếu một lớp con kế thừa một lớp cha, nó phải có khả năng sử dụng ở bất kỳ đâu mà lớp cha được sử dụng mà không làm thay đổi tính đúng đắn của chương trình, cho phép dễ dàng thêm mới các lớp con mà không cần sửa đổi mã nguồn hiện có, giúp hệ thống linh hoạt hơn và dễ dàng mở rộng

Ví dụ minh họa: Trong cuộc sống, khi đi mua sắm, ăn uống, để thanh toán cho các loại chi phí thì có rất nhiều cách để thực hiện: thẻ ngân hàng, ví điện tử, Để triển khai vấn đề này thành 1 chương trình nên áp dụng nguyên lí L trong SOLID principles vào tối

ưu hóa chương trình

Trang 15

BTLT-Group-W09-10 GVHD: Hồ Tuấn Thanh

13

class DigitalWalletPayment : public Payment

{

public:

void pay(float money)

{

std::cout << "Processing digital wallet payment of " << money << std::endl;

}

};

class PayPalPayment : public Payment

{

public:

void pay(float money)

{

std::cout << "Processing PayPal payment of " << money << std::endl;

}

};

class MobileAppPayment : public Payment

{

public:

void pay(float money)

{

std::cout << "Processing mobile app payment of " << money

}

};

Trang 16

class Document {

public:

virtual void

virtual void

virtual void

virtual void

virtual void

};

createDocument( )

readDocument()

=

updateDocument

()

deleteDocument( )

= 0;

0;

= 0;

= 0;

convertDocument() = 0;

4 (2đ) Tìm hiểu nguyên lý I trong SOLID principles Cho ví dụ minh họa thực tế.

Nguyên lý I trong SOLID principles là nguyên lý phân tách giao diện ( Interface Segregation principle - ISP) Nội dung của nguyên lý I như sau: "Không nên bắt các khách hàng phải phụ thuộc vào những giao diện mà họ không sử dụng” Nói cách khác, thay vì tạo ra một giao diện lớn chứa nhiều phương thức mà không phải tất cả khách hàng đều cần đến, ta nên tạo ra nhiều giao diện nhỏ, chuyên biệt

Áp dụng nguyên lý ISP làm giảm sự phụ thuộc không cần thiết, các lớp chỉ phụ thuộc vào những giao diện mà chúng thực sự cần Khi các giao diện nhỏ gọn và chuyên biệt, việc thay đổi chúng ít ảnh hưởng đến các phần khác của hệ thống Ngoài ra cũng tăng khả năng tái sử dụng của các giao diện qua các lớp khác nhau mà không gây gánh nặng cho các lớp này

dụ minh họa: Khi tạo 1 interface Document với quá nhiều phương thức khác nhau: createDocument, readDocument, deleteDocument, và còn nhiều phương thức khác nữa, nhưng không phải loại tài liệu nào cũng cần sử dụng hết toàn bộ các phương thức đó, điều này vi phạm nguyên lí I trong SOLID principles

Thay vì tạo như 1 interface quá lớn như vậy thì nên áp dụng nguyên lí ISP vào trường hợp này để tối ưu hơn

Trang 17

BTLT-Group-W09-10 GVHD: Hồ Tuấn Thanh

15

class CreateDocument

{

public:

virtual void createDocument() = 0;

};

class ReadDocument

{

public:

virtual void readDocument() = 0;

};

class UpdateDocument

{

public:

virtual void updateDocument() = 0;

};

class DeleteDocument

{

public:

virtual void deleteDocument() = 0;

};

class ConvertDocument

{

public:

virtual void convertDocument() = 0;

};

Trang 18

BTLT-Group-W09-10 GVHD: Hồ Tuấn Thanh

5 (2đ) Tìm hiểu nguyên lý D trong SOLID principles Cho ví dụ minh họa thực tế.

Nguyên lý D trong SOLID là viết tắt của Dependency Inversion Principle Nội dung của nguyên lý này có 2 ý như sau:

 “Các module cấp cao không nên phụ thuộc vào các module cấp thấp Cả hai nên phụ thuộc vào abstraction (interface).”

 “Abstraction (interface) không nên phụ thuộc vào chi tiết Ngược lại, chi tiết (concrete implementation) nên phụ thuộc vào abstraction (interface).”

Nguyên lý này gợi ý cho chúng ta cách thiết kế và cài đặt chương trình tốt hơn về mặt nâng cấp, mở rộng, hay chỉnh sửa lại các chức năng Khi áp dụng nguyên tắc này, việc nâng cấp, mở rộng, chỉnh sửa các chức năng sẽ trở nên nhanh chóng và dễ dàng hơn

Vì khi đó, chúng ta sẽ chỉ cần chỉnh sửa trên các abstract class và các concrete class sẽ được tự động kế thừa Như vậy, chúng ta sẽ không cần phải chỉnh sửa trên tất cả các class liên quan đến chức năng mà chúng ta cần thay đổi

Một ví dụ thực tế và quen thuộc trong cuộc sống như sau: Chúng ta có rất nhiều thiết

bị điện tử khác nhau trong nhà như tivi, tủ lạnh, máy giặt, … Nhưng dù là thiết bị nào thì cũng sẽ có dây cắm là loại phích cắm 2 chấu Vậy thì mỗi khi chúng ta muốn sử dụng loại thiết bị nào đó thì chỉ cần lấy phích cắm nối vào ổ điện mà không cần quan tâm loại thiết

bị đó là gì

Trong ví dụ trên có thể xem phích cắm 2 chấu là một interface (abstraction), các thiết bị điện tử là một concrete class Khi cần thay đổi gì đó thì chỉ cần thay đổi trên interface (abstraction) là được Như ở Việt Nam thì hầu hết sử dụng phích 2 chấu, còn ở một số nước khác sẽ sử dụng phích 3 chấu Như vậy thì chỉ cần thay đổi interface (abstraction) 2 chấu thành 3 chấu là hoàn thành mà không cần thay đổi các thiết bị điện tử

Ngày đăng: 11/12/2024, 10:24