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 );
};
11 trang |
Chia sẻ: thienmai908 | Lượt xem: 1249 | Lượt tải: 0
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:
- jyksagupierh'iufgoasidu[ps (7).pdf