You are on page 1of 7

Nguyễn Hoài Danh - 1610391

Lab 9
Câu 1:

b) Chương trình in ra:

L1: “In A(), value = 123”


L2: “In A(int value), value = 246”
L3: “In A(int value), value = 456”
L4: “In A(const A& ob), value = 123”
L5: “In ~A(), value = 123”
L6: “In ~A(), value = 456”
L7: “In ~A(), value = 246”
L8: “In A(int value), value = 789”
L9: “In A(int value), value = 357 “

Các dòng 1,2,3,4,8,9 in ra các giá trị của biến value ứng với các cách gọi hàm tạo đã định
nghĩa.

Riêng với L5,L6 thì vì đối tượng ob2, ob3 ra khỏi tầm vực ( “{ }”) của nó nên hàm hủy sẽ tự
động được gọi nên in ra màn hình như đã định nghĩa trong hàm hủy. Với L7 thì do ta chủ động trả bộ
nhớ cho hệ thống qua câu lệnh “delete ptr1” nên hàm hủy cũng được gọi và xuất ra kết quả như line
7.

c) Hàm ~A(): là hàm hủy, nó được gọi khi đối tượng ra khỏi tầm vực hoặc người dùng chủ
động gọi nó.
d) Nếu xoá bỏ dòng “public:”, biên dịch lại chương trình có lỗi vì khi đó các hàm tạo ở trong
tính khả kiến “private” nên trong hàm main ta không được phép truy cập nên sẽ báo lỗi.
e) Nếu thay chữ “private” thành “protected”, biên dịch lại chương trình thì cũng sẽ báo lỗi.
Vì “protected” chỉ được truy cập trong các phương thức thành viên của class đó hoặc
các lớp dẫn xuất của nó mà thôi.
f) Nếu xoá bỏ toàn bộ hàm khởi tạo A(). Biên dịch lại chương trình có lỗi. Vì trong trường
hợp này trình biên dịch không xác định được hàm khởi tạo mặc định.
g) Nếu xoá bỏ toàn bộ hàm khởi tạo A(const A& ob). Biên dịch lại chương trình sẽ không
có lỗi vì trong trường hợp này trình biên dịch sẽ tạo ra một hàm tạo mặc định và nó
không làm công việc như hàm tạo A(const A& ob) đã định nghĩa.
h) Nếu xoá bỏ toàn bộ hàm huỷ. Biên dịch lại chương trình không có lỗi vì khi đó hệ thống
sẽ tự tạo ra một hàm hủy mặc định không làm gì cả, nên sẽ không in các câu lệnh trong
hàm hủy:
L5: “In ~A(), value = 123”
L6: “In ~A(), value = 456”
L7: “In ~A(), value = 246”
i) Thay vì khởi động biến m_value trên dòng khởi tạo, như “A():
m_value(123)” ta viết :
“A() {
m_value = 123;
cout << "In A(), value = " << m_value << endl;
}”
Câu 2:
#include <iostream>
#include <iomanip>
using namespace std;
class X {
public:
int m_value;
};
class Y : public X {
public:
int m_value;
};
class Z : public Y {
public:
Z(int vx, int vy, int vz) {
/////////////////////////
X::m_value = vx;
Y::m_value = vy;
this->m_value = vz;
/////////////////////////
}
public:
int m_value;
};
int main() {
Z obj(1, 2, 3);
//(2)
cout <<obj.X::m_value <<","<<obj.Y::m_value<<","<<obj.m_value << endl;
///////////////////////////
system("pause");
return 0;
};

Câu 3:

a) Chương trình không báo lỗi. In ra:


“class X
class Y
class Z
class Z”
b) Nếu thay từ khoá public trong “class Z: public Y” thành protected, biên dịch lại có lỗi. Vì các
thành viên (thuộc tính + phương thức) có tính public của X và Y sẽ đều có tính private trong
ClassZ nên trong hàm main không được phép truy cập ở câu lệnh:

“obj.X::display();
obj.Y::display();”
c) Nếu thay từ khoá public trong “class Y: public X” thành protected, biên dịch lại có
lỗi. Vì các thành viên (thuộc tính + phương thức) có tính public của X sẽ có tính protected
trong ClassY. Nên trong hàm main không được phép truy cập ở câu lệnh:
“ obj.X::display();”
d) Nếu thay từ khoá public trong “lớp X” thành protected, biên dịch lại có lỗi. Vì Các thành viên
trong class có thuộc tính private nên không được truy cập được trong hàm main với câu
lệnh: “obj.X::display();”
Câu 4:

a) Chương trình in ra:

L1:“Call method via NON-POINTER variable - CASE I:

Type of "this" object is: Class X

Type of "this" object is: Class Y

Type of "this" object is: Class Z

Call method via NON-POINTER variable - CASE II:

Type of "this" object is: Class X

Type of "this" object is: Class X

Type of "this" object is: Class X

Call method via POINTER variable - CASE I:

Type of "this" object is: Class X

Type of "this" object is: Class Y

Type of "this" object is: Class Z

Call method via POINTER variable - CASE II:

Type of "this" object is: Class X

Type of "this" object is: Class X

Type of "this" object is: Class X”

Dòng 2 3 4 thực hiện và in ra nội dung của các hàm display của các class X,Y,Z bình thường

Dòng 6,7,8 in ra nội dung “Type of "this" object is: Class X” vì phép gán x1=y1 thì chỉ nội dung của các
thuộc tính , phương thức mà Y được kế thừa từ X mới gán cho x1 nên khi gọi hàm thì in ra dung
“Type of "this" object is: Class X” mà không phải dung “Type of "this" object is: Class Y” tương tự với
x2=y2, x3=y3.

Dòng 10,11,12 thực hiện và in ra nội dung của các hàm display của các class X,Y,Z bình thường.

X *px1 = new X();


X *px2 = new Y();
X *px3 = new Z();

Các các lệnh này sẽ xin cấp phát vùng nhớ chứa đối tượng kiểu lần lượt là
X,Y,Z nhưng các con trỏ px1,px2,px3 vẫn là kiểu X nên khi gọi hàm display

sẽ hiển thị cùng 1 nội dung “Type of "this" object is: Class X”

b) Thêm từ khóa “virtual” vào thì :


X *px1 = new X();
X *px2 = new Y();
X *px3 = new Z();

Sẽ in ra:

Type of "this" object is: Class X

Type of "this" object is: Class Y

Type of "this" object is: Class Z

Vì Thừa kế ảo (virtual) giúp cho đối tượng của lớp cha (Class X) ở

trên) chỉ được cấp phát một lần.

Câu 5:

a) Thêm vào lớp Y là lớp con của lớp X. Định nghĩa lại (override) phương thức display

trong X, sao cho bên ngoài lớp Y vẫn gọi được – như dòng: “y.display();“ trong hàm main:
class Y : public X {
public:
void display()
{
X::display();
}
};

b) Thêm vào lớp Z là lớp con của lớp Y. Định nghĩa lại (override)
phương thức display thừa kế được từ lớp Y, sao cho bên ngoài lớp Z
không thể dùng phương thức display được nữa – như dòng:
“z.display();“ trong hàm main:
Cách 1:
class Z : public Y {
private:
void display() {
X::display();
}
};
int main() {
X x;
X y;
Z z;
x.display(); //OK
y.display(); //OK
z.display(); //Error during compilation
system("pause");
return 0;
};
Cách 2:
class Z : public Y {
protected:
void display() {
X::display();
}
};
int main() {
X x;
X y;
Z z;
x.display(); //OK
y.display(); //OK
z.display(); //Error during compilation
system("pause");
return 0;
};

Câu 6:
#include<iostream>
#include<iomanip>
#include<string>
#include<sstream>
using namespace std;
class Date {
public:
int day, month, year;
Date()
{
this->day = 25;
this->month = 2;
this->year = 2017;
}
void tostring()
{
string temp;
if (this->day < 10)
cout << "0" << this->day << "/";
else cout << this->day << "/";
if (this->month<10)
cout << "0" << this->month << "/" << this->year << endl;
else cout << this->month << "/" << this->year << endl;
}
};
Date operator+(Date date) // + : toán tử cin
{
Date date1;
string temp;
getline(cin, temp);
stringstream temp1(temp);
char temp2;
temp1 >> date1.day >> temp2 >> date1.month >> temp2 >> date1.year;
return date1;
}
Date operator++(Date date) // ++: toan tử in ra them số 0
{
string temp;
if (date.day < 10)
cout << "0" << date.day << "/";
else cout << date.day << "/";
if (date.month<10)
cout << "0" << date.month << "/" << date.year << endl;
else cout << date.month << "/" << date.year << endl;
return date;
}
bool operator<(Date date1, Date date2) //<: toan tu so sanh
{
if (date1.year < date2.year)return true;
else if (date1.year > date2.year)return false;
else if (date1.year == date2.year)
{
if (date1.month < date2.month)return true;
else if (date1.month > date2.month)return false;
else if (date1.month == date2.month)
{
if (date1.day < date2.month)return true;
else return false;
}
}
}
int main()
{
Date d1, d2;
cout << "Enter date:";
d1=+d1;
cout << "Enter date:";
d2=+d2;
++ d1;
++ d2;
cout << (d1 < d2 ? "d1<d2" : "d1>=d2") << endl;
Date d3;
d3.tostring() ;
system("pause");
return 0;
}

You might also like