1/ Khái niệm
Một đối tượng được gán cho một đối tượng khác để cả hai đối tượ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
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 đối tượng chỉ áp dụng cho các đối tượ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"; } };
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 đối tượ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;
// 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";
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 chắn rằng không hủy bỏ các thông tin cần thiết trong đối tượ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";
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 {
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.