Câu 1: Trình bày về: Phương thức thiết lập (Constructor), các dạng phương

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 9

Câu 1: Trình bày về: Phương thức thiết lập (Constructor), các dạng phương

thức thiết lập, cho ví dụ minh hoạ; Phương thức huỷ bỏ (Destructor) trong lập
trình hướng đối tượng. Cho ví dụ minh hoạ với các trường hợp trên và giải
thích.
 Phương thức thiết lập (Constructor): là một hàm đặc biệt trong lớp. Hàm
này được gọi tự động khi một đối tượng được tạo ra. Hàm khởi tọ sẽ khởi tạo
giá trị cho các thuộc tính của đối tượng. Trong C++, một hàm khởi tạo có
những đặc điểm như sau:
 Tên hàm khởi tạo trùng với tên của lớp.
 Hàm khởi tạo không có kiểu dữ liệu trả về (kể cả void).
 Hàm khởi tạo phải được khai báo với phạm vi truy cập là public.
 Hàm khởi tạo có thể có đối số hoặc không có đối số.
 Trong một lớp có thể có nhiều hàm khởi tạo (cùng tên nhưng khác đối
số).
 Các dạng phương thức thiết lập:
 Phương thức thiết lập mặc định (default constructor): là phương thức
thiết lập nhận tham số đầu vào là 1 đối tượng thuộc cùng 1 lớp. Các thông
tin ban đầu cho đối tượng của lớp bằng những giá trị mặc định (do lập
trình viên quy định). Phương thức thiết lập mặc định không có đối số.

 Phương thức thiết lập sao chép (copy constructor): là phương thức
thiết lập nhận tham số đầu vào là 1 đối tượng thuộc cùng 1 lớp. Các thông
tin ban đầu của đối tượng sẽ hoàn toàn giống thông tin của đối tượng
tham số đầu vào.
 Phương thức thiết lập có tham số: là phương thức thiết lập không thuộc
2 loại trên. Các thông tin ban đầu của đối tượng sẽ phụ thuộc vào các
tham số của phương thức thiết lập.

 Phương thức hủy bỏ (Destructor): có nhiệm vụ thu hồi lại bộ nhớ cấp phát
cho đối tượng thuộc lớp ngay khi đối tượng hết phạm vi hoạt động. Các đặc
điểm của phương thức hủy:
 Có tên trùng với tên lớp (có them dấu ~ phía trước).
 Không có giá trị trả về và cũng không nhận tham số đầu vào.
 Mỗi lớp chỉ có nhiều nhất 1 phương thức hủy. Nếu lập trình viên không
xây dựng hàm hủy thì trình biên dịch sẽ tạo ra một phương thức hủy mặc
định.
 Phương thức hủy chỉ được tự động gọi thực hiện một lần duy nhất (khi
đối tượng hết phạm vi hoạt động).
 Phương thức hủy phải được xây dựng khi trong phương thức khởi tạo, ta
có sử dụng các hàm cấp phát bộ nhớ thì ta bắt buộc phải xây dựng
phương thức hủy để thu hồi các bộ nhớ này lại.

Câu 2: Định nghĩa lớp CDate biểu diễn khái niệm ngày, tháng, năm với phép
toán <<, >> để xuất, nhập dữ liệu loại CDate và phép toán cộng (+) dữ liệu
Cdate với một số ngày n và phép trừ (-) dữ liệu Cdate với một số ngày n.

#include <iostream>
using namespace std;

class CDate {
private:
int Day, Month, Year;
bool LeapYear;
int months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool isLeapYear(int year) {
return (year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0));
}

public:
CDate(int newday, int newmonth, int newyear) {
Day = newday;
Month = newmonth;
Year = newyear;
LeapYear = isLeapYear(newyear);
if (LeapYear)
months[1] = 29;
}

friend istream &operator>>(istream &is, CDate &date) {


cout << "Ngay: ";
is >> date.Day;
cout << "Thang: ";
is >> date.Month;
cout << "Nam: ";
is >> date.Year;

while (date.Year < 1 || date.Month < 1 || date.Month > 12 ||


date.Day < 1 || date.Day > date.months[date.Month - 1]) {
cout << "Sai. Nhap lai.\n";
cout << "Ngay: ";
is >> date.Day;
cout << "Thang: ";
is >> date.Month;
cout << "Nam: ";
is >> date.Year;
}

date.LeapYear = date.isLeapYear(date.Year);
if (date.LeapYear)
date.months[1] = 29;

return is;
}

friend ostream &operator<<(ostream &os, const CDate &date) {


os << date.Day << '/' << date.Month << '/' << date.Year;
return os;
}

void Check() {
while (Day > months[Month - 1]) {
Day -= months[Month - 1];
Month++;
if (Month == 13) {
Year++;
LeapYear = isLeapYear(Year);
if (LeapYear)
months[1] = 29;
else
months[1] = 28;
Month = 1;
}
}
while (Day < 1) {
Month--;
if (Month == 0) {
Year--;
Month = 12;
LeapYear = isLeapYear(Year);
if (LeapYear)
months[1] = 29;
else
months[1] = 28;
}
Day += months[Month - 1];
}
}

CDate operator+(int news) {


CDate Tong(Day, Month, Year);
Tong.Day += news;
Tong.Check();
return Tong;
}

CDate operator-(int news) {


CDate Tong(Day, Month, Year);
Tong.Day -= news;
Tong.Check();
return Tong;
}
};

int main() {
CDate date(1, 1, 2024);
cout << "Nhap ngay thang nam: ";
cin >> date;
cout << "\nThoi gian vua nhap: " << date << endl;
int daysadd, dayssub;
cout << "\nNhap so ngay ban muon cong them: ";
cin >> daysadd;
cout << "\nThoi gian sau khi cong: " << date + daysadd;
cout << "\nNhap so ngay ban muon tru di: ";
cin >> dayssub;
cout << "\nThoi gian sau khi tru: " << date - dayssub;
return 0;
}

Câu 3:
a) Sơ đồ:
b)

#include <bits/stdc++.h>
using namespace std;

class NhanVien{
protected:
string HoTen, DiaChi, DT;
public:
NhanVien(string HoTen, string DiaChi, string DT): HoTen(HoTen),
DiaChi(DiaChi), DT(DT) {}
virtual void Nhap(){
cout << "Nhap ho ten nhan vien: ";
getline(cin, HoTen);
cout << "Nhap dia chi: ";
getline(cin, DiaChi);
cout << "Nhap so dien thoai: ";
getline(cin, DT);
}
virtual void Xuat() const {
cout << "Ho ten: " << HoTen << endl;
cout << "Dia chi: " << DiaChi << endl;
cout << "So dien thoai: " << DT << endl;
}
virtual double Luong() const = 0;
virtual ~NhanVien() = default;
};
class LuongTheoThang : public NhanVien{
private:
double LuongCB;
public:
LuongTheoThang(string HoTen, string DiaChi, string DT, double
LuongCB) : NhanVien(HoTen, DiaChi, DT), LuongCB(LuongCB) {}
void Nhap() override {
cout << "Nhap muc luong: ";
cin >> LuongCB;
}
void Xuat() const override {
cout << "Luong: " << fixed << setprecision(0) << LuongCB << endl;
}
};
class LuongTheoGio : public NhanVien {
private:
int SoGioLamViec;
double TienCong1h;
public:
LuongTheoGio(string HoTen, string DiaChi, string DT, int SoGioLamViec,
double TienCong1h)
: NhanVien(HoTen, DiaChi, DT), SoGioLamViec(SoGioLamViec),
TienCong1h(TienCong1h) {}
void Nhap() override {
cout << "Nhap so gio lam viec: ";
cin >> SoGioLamViec;
cout << "Nhap so tien cong moi gio: ";
cin >> TienCong1h;
}
void Xuat() const override {
cout << "So gio lam viec: " << SoGioLamViec << endl;
cout << "Tien cong moi gio: " << fixed << setprecision(0) <<
TienCong1h << endl;
cout << "Luong: " << fixed << setprecision(0) << Luong() << endl;
}
double Luong() const override {
return SoGioLamViec * TienCong1h;
}
};
class LuongHoaHong : public NhanVien {
private:
double DoanhThu;
int TyLe;
public:
LuongHoaHong(string HoTen, string DiaChi, string DT, double DoanhThu,
int TyLe)
: NhanVien(HoTen, DiaChi, DT), DoanhThu(DoanhThu), TyLe(TyLe)
{}
void Nhap() override {
cout << "Nhap tong doanh thu: ";
cin >> DoanhThu;
cout << "Nhap ty le huong hoa hong: ";
cin >> TyLe;
}
void Xuat() const override {
cout << "Tong doanh thu: " << fixed << setprecision(0) << DoanhThu
<< endl;
cout << "Ty le huong hoa hong: " << TyLe << endl;
}
double Luong() const override {
return DoanhThu * (TyLe / 100);
}
};
class HangHoa{
private:
string TenSP;
int SoLuong;
double Gia;
public:
HangHoa(string TenSP, int SoLuong, double Gia) : TenSP(TenSP),
SoLuong(SoLuong), Gia(Gia) {}
void Nhap(){
cin.ignore();
cout << "Nhap ten san pham: ";
getline(cin, TenSP);
cout << "Nhap so luong: ";
cin >> SoLuong;
cout << "Nhap don gia: ";
cin >> Gia;
}
void Xuat() {
cout << "Ten SP: " << TenSP << endl;
cout << "So luong: " << SoLuong << endl;
cout << "Don gia: " << fixed << setprecision(0) << Gia << endl;
}
int getSoLuong() const {
return SoLuong;
}
int getGia() const {
return Gia;
}

};

struct HoaDon {
string Id;
string Date;
vector<HangHoa> DanhSachHang;
int64_t TongTien() const {
int64_t sum = 0;
for (const auto& hang : DanhSachHang) {
sum += hang.getGia() * hang.getSoLuong();
}
return sum;
}
void Nhap() {
cout << "Nhap so hoa don: ";
getline(cin, Id);
cout << "Nhap ngay hoa don: ";
getline(cin, Date);
int n;
cout << "Nhap so luong hang hoa: ";
cin >> n;
for (int i = 0; i < n; ++i) {
cout << "----------------------" << endl;
HangHoa h("none", 0, 0);
h.Nhap();
DanhSachHang.push_back(h);
}
}
};

You might also like