Lập trình hướng đối tượng Phần 7

Nhân ma trận với một số thực

Nhân một số thực với ma trận

class MATRIX{

//.

public:

MATRIX operator*( double );

friend MATRIX operator*

( double,MATRIX );

};

pdf11 trang | Chia sẻ: thienmai908 | Lượt xem: 1149 | Lượt tải: 0download
Nội dung tài liệu Lập trình hướng đối tượng Phần 7, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
11 Object – Oriented Programming PGS. TS. Trần Văn Lăng KHOA CÔNG NGHỆ THÔNG TIN TRƯỜNG ĐẠI HỌC LẠC HỒNG lang@lhu.edu.vn 2 Chương 7 Phép toán 3 Phép toán trong C++ Ngôn ngữ C++ cho phép cài đặt các phép toán một cách tiện lợi và tự nhiên. Tên gọi của phép toán được đặt theo quy ước gồm hai phần,  Phần bắt buộc - sử dụng từ khóa operator  Phần do người lập trình chọn lựa trong tập hợp các ký hiệu phép toán của ngôn ngữ. 4 Ví dụ Cộng hai VECTOR với nhau VECTOR operator+ (VECTOR u,VECTOR v){ //... } 25 Các ký hiệu không sử dụng Laáy kích thö ôùc cuûa kieåu dö õlieäusizeof() Pheùp toaùn ñieàu kieän?: Truy caäp ñeán thaønh phaàn cuûa ñoái tö ôïng hay cuûa struct . Truy caäp ñeán con troûlaøthaønh phaàn ñoái tö ôïng hay struct .* Truy caäp ñeán thaønh phaàn cuûa lôùp:: YÙ nghóaPheùp toaùn 6 Phép toán là thành viên của lớp Phép toán là hành vi, nên có thể hiện thực như thành phần thuộc lớp. Với phép toán hai ngôi phải có hai tham số hình thức, khi trở thành phương thức của lớp chỉ còn một tham số. 7 Ví dụ: phép toán cộng (ký hiệu +) Giả sử có kiểu dữ liệu vector v = (v1,v2), trong đó v1, v2 là 2 số thực. Khi đó, phép toán cộng 2 vector được định nghĩa như sau, cho u = (u1,u2), v = (v1,v2), thì w = (w1,w2), w = u + v w1 = u1 + v1, w2 = u2 + v2 8 Từ đó, Ta có thể xây dựng lớp VECTOR với phép toán + như sau: VECTOR::VECTOR operator + (VECTOR v){ VECTOR w; w.x = x + v.x; w.y = y + v.y; return w; } Chỉ còn 1 tham số 39 Bổ sung thêm Phép toán lấy đối xứng qua gốc toạ độ, ký hiệu bằng dấu trừ (-). Phép toán được định nghĩa như sau, cho u = (u1,u2), v = -u v1 = -u1, v2 = -u2 10 Từ đây có thể hiện thực VECTOR::VECTOR operator - (){ VECTOR v; v.x = -x; v.y = -y; return v; } Không có tham số nào 11 Chúng ta có thể, Dùng cùng 1 ký hiệu cho nhiều phép toán, chẳng hạn: class VECTOR{ double x,y; public: //... VECTOR operator + ( VECTOR ); VECTOR operator - (); VECTOR operator - ( VECTOR ); }; Phép toán trừ 2 Vector 12 Ngoài ra, Có thể đưa vào trong kiểu dữ liệu nhiều phép toán phức tạp hơn, Chẳng hạn, nhân Vector với 1 số, hoặc nhân 1 số với Vector:  V = kU, hay V = Uk, trong đó k là số thực, còn U và V là 2 Vector.  Khi đó có thể sử dụng ký hiệu * để hiện thực hai phép toán nhân này. 413 Ở đây, Nếu phép toán được hiện thực như một hàm bình thường dạng: VECTOR operator * (double k,VECTOR U) Nhưng khi hàm này là thành viên của lớp, cần đến khái niệm friend. Do toán hạng thứ nhất không thuộc lớp này. 14 Hàm friend Để chỉ định quan hệ phụ thuộc friend, chúng ta phải mô tả hàm bên trong lớp với từ khóa friend phía trước hàm. Khi đó, hàm bên ngoài lớp có thể coi như là thành viên của lớp – có thể truy cập đến các thành viên của lớp. 15 Ví dụ Đưa một hàm không thuộc lớp trở thành thành viên của lớp: class DOUBLE{ double data; public: friend DOUBLE add(DOUBLE, DOUBLE); }; 16 Lớp friend Khi không những chỉ một hàm nào đó, mà các hành vi của lớp được quyền truy cập đến những thành viên có thuộc tính private, protected của một lớp khác Chẳng hạn, các hành vi của lớp A, muốn truy cập những thành viên private, protected của lớp B, thì trong lớp B phải mô tả lớp A có thuộc tính là friend. 517 class A{ //... public: friend class B; //... }; class B{ //... }; 18 Phép toán là friend của lớp class VECTOR{ double x,y; public: //... VECTOR operator + ( VECTOR ); VECTOR operator - (); VECTOR operator - ( VECTOR ); friend VECTOR operator * (double,VECTOR); VECTOR operator * ( double ); }; Cho phép toán V = Uk Đây là phép toán V = kU 19 Phức tạp hơn, coi phép toán ++ Phép toán này được xét tương tự phép toán --. Đây là phép toán tồn tại ở 2 cách sử dụng, nên có thể coi như 2 phép toán khác nhau khi hiện thực:  Phép toán tăng trước (dạng ++n): đây là phép toán 1 ngôi  Và tăng sau (dạng n++): có thể coi là phép toán 2 ngôi, ngôi thứ hai thuộc kiểu int 20 Ví dụ: class DOUBLE{ double data; public: DOUBLE( double = 0.0 ); DOUBLE operator ++ (); DOUBLE operator ++ ( int ); }; 621 Trong đó, DOUBLE DOUBLE::operator++(){ data += 10.0; return *this; } DOUBLE DOUBLE::operator++(int){ DOUBLE t = *this; data += 10.0; return t; } Tăng trước nên sau khi tăng lên thì trả về chính nó Bởi tăng sau, nên bản thân nó không được thay đổi, lấy lại cái ban đầu 22 Sử dụng, Tạo một hàm main() để sử dụng như bình thường. Chẳng hạn, main(){ DOUBLE a, b = 5.3; a = ++b; } 23 Phép toán () Đây cũng là phép toán khá thú vị, phép toán này dùng để gọi hàm. Phép toán có 2 ngôi (2 toán hạng).  Toán hạng thứ nhất là tên hàm;  Thứ hai là danh sách các tham số thực Lợi dụng đặc tính này để truy cập đến phần tử của mảng bằng cách viết tên(chỉ số) 24 Chẳng hạn, a(i), b(i,j), c(10,k,5) để truy cập đến từng phần tử của mảng một chiều a, mảng hai chiều b và mảng ba chiều c. Trong đó danh sách tham số thực lần lượt là i; i,j và 10,k,5 725 Ví dụ class MOTChieu{ int size; double *data public: MOTChieu( int = 2 ); double& operator()( int ); }; Mảng một chiều có size phần tử 26 MOTChieu::MOTChieu( int n ){ size = n; data = new double[size]; } double& MOTChieu::operator()(int i){ return data[i]; } Tên hàm được dùng như toán hạng thứ nhất của phép toán gán 27 Hoặc với mảng 2 chiều class HAIChieu{ int row, col; double **data public: HAIChieu( int = 2, int = 2 ); double& operator()( int, int ); }; 28 HAIChieu::HAIChieu( int r, int c ){ row = r; col = c; data = new double*[row]; double *t = new double[row*col]; for( int i = 0; i < row; i++, t+= col ) data[i] = t; } double& HAIChieu::operator()(int i,int j){ return data[i][j]; } Cấp phát bộ nhớ cho mảng 2 chiều 829 Lớp ma trận, có các phép toán Truy cập phần tử Nhân 2 ma trận với nhau Cộng 2 ma trận Gán các phần tử của ma trận bởi một số Gán ma trận này bởi ma trận khác Xuất ma trận ra màn hình 30 Để thực hiện, trước hết Xây dựng lớp dạng mảng hai chiều, lớp có  Dữ liệu là con trỏ  Constructor  Destructor  Copy constructor 31 class MATRIX{ int row, col; double **data; public: MATRIX( int = 2, int = 2 ); MATRIX ( MATRIX& ); ~MATRIX(); //... }; 32 Và các phép toán class MATRIX{ //... public: double& operator()( int, int ); MATRIX operator=( double ); MATRIX operator*( MATRIX ); MATRIX operator=( MATRIX ); MATRIX operator+( MATRIX ); friend ostream& operator<< (ostream,MATRIX&); }; 933 Cũng có thể mở rộng thêm Nhân ma trận với một số thực Nhân một số thực với ma trận class MATRIX{ //... public: MATRIX operator*( double ); friend MATRIX operator* ( double,MATRIX ); }; 34 Constructor MATRIX::MATRIX( int r, int c ){ row = r; col = c; data = new double*[row]; double *t = new double[row*col]; for( int i = 0; i < row; i++, t+= col ) data[i] = t; } Cấp phát bộ nhớ như mảng 2 chiều 35 Copy Constructor MATRIX::MATRIX( MATRIX& B ){ row = B.row; col = B.col; data = new double*[row]; double *t = new double[row*col]; for( int i = 0; i < row; i++, t+= col ) data[i] = t; for( i = 0; i < row; i++ ) for ( int j = 0; j < col; j++ ) data[i][j] = B(i,j); } Chép dữ liệu từ B qua Cấp phát bộ nhớ mới 36 Destructor MATRIX::~MATRIX(){ delete []*data; delete []data; } Xoá vùng dữ liệu và vùng chứa con trỏ 10 37 Một vài phép toán MATRIX MATRIX::operator*( MATRIX B ){ MATRIX C(row,B.col); for( int i = 0; i < row; i++ ) for( int j = 0; j < B.col; j++ ){ C(i,j) = 0.0; for( int k = 0; k < col; k++ ) C(i,j) += data[i][k]*B(k,j); } return C; } Nhân ma trận 38 Phép toán gán MATRIX MATRIX::operator=( MATRIX B ){ for( int i = 0; i < row; i++ ) for ( int j = 0; j < col; j++ ) data[i][j] = B(i,j); return *this; } 39 Phép toán xuất ostream& operator<< ( ostream& out, MATRIX& B ){ for( int i = 0; i < B.row; i++ ){ for ( int j = 0; j < B.col; j++ ) out << B(i,j) << ", "; out << endl; } return out; } 40 main(){ MATRIX A(3,4); A = 5.0; cout << A << endl; MATRIX B(4,2); B = 2.0; cout << B << endl; MATRIX C(3,2); C = A * B; cout << C << endl; MATRIX D(3,4), E(3,4); D = 3.0; E = A + D; cout << E << endl; D = E*2; cout << D << endl; E = 2*D; cout << E << endl; } 11 41 Yêu cầu Biết cách thức viết hàm phép toán trong lớp của ngôn ngữ C++ Hoàn thiện kiểu dữ liệu lớp sao cho có các hành vi:  Truy cập dữ liệu (nhập/xuất; nhận biết/thay đổi giá trị của dữ liệu)  Các phép toán liên quan  Các hành vi đặc thù

Các file đính kèm theo tài liệu này:

  • pdfjyksagupierh'iufgoasidu[ps (7).pdf
Tài liệu liên quan