30/09/2018, 17:03

Thừa kế và thuộc tính của 1 lớp là đối tượng của lớp khác

Em có đoạn code sau:

#include <iostream>
#include <cstring>
#include "Date.cpp"

using namespace std;

class ConNguoi{
	private:
		char * HoTen;
		char * GioiTinh;
		Date NamSinh;
		char * NoiSinh;
		char * DiaChi;
	public:
		ConNguoi();
		ConNguoi(const ConNguoi& tmp);
		ConNguoi& operator = (const ConNguoi& tmp){
			delete [] HoTen;
			delete [] GioiTinh;
			delete [] NoiSinh;
			delete [] DiaChi;
			HoTen = new char[50];
			strcpy(HoTen, tmp.HoTen);
			GioiTinh = new char[5];
			strcpy(GioiTinh, tmp.GioiTinh);
			NamSinh = tmp.NamSinh;
			NoiSinh = new char[100];
			strcpy(NoiSinh, tmp.NoiSinh);
			DiaChi = new char[100];
			strcpy(DiaChi, tmp.DiaChi);
			return *this;
		};
		~ConNguoi();
		friend ostream& operator << (ostream& os, ConNguoi tmp);
		friend istream& operator >> (istream& is, ConNguoi& tmp);
};
ConNguoi::ConNguoi():NamSinh(1,1,2000){
	HoTen = new char[50];
	strcpy(HoTen, "");
	GioiTinh = new char[5];
	strcpy(GioiTinh, "");
	NoiSinh = new char[100];
	strcpy(NoiSinh, "");
	DiaChi = new char[100];
	strcpy(DiaChi, "");
}

ConNguoi::ConNguoi(const ConNguoi& tmp):NamSinh(tmp.NamSinh){
	HoTen = new char[50];
	strcpy(HoTen, tmp.HoTen);
	GioiTinh = new char[5];
	strcpy(GioiTinh, tmp.GioiTinh);
	NoiSinh = new char[100];
	strcpy(NoiSinh, tmp.NoiSinh);
	DiaChi = new char[100];
	strcpy(DiaChi, tmp.DiaChi);
}

ConNguoi::~ConNguoi(){
	delete [] HoTen;
	delete [] GioiTinh;
	delete [] NoiSinh;
	delete [] NoiSinh;
}

ostream& operator << (ostream& os, ConNguoi tmp){
	os << "Ho ten " << tmp.HoTen;
	os << "Gioi tinh " << tmp.GioiTinh;
	os << "Nam sinh "; tmp.NamSinh.Xuat();
	os << "Noi sinh " << tmp.NoiSinh;
	os << "Dia chi " << tmp.DiaChi;
	return os;
}

istream& operator >> (istream& is, ConNguoi& tmp){
	cout << "Nhap ho ten " << endl;
	is.getline(tmp.HoTen, 50);
	cout << "Gioi tinh " << endl;
	is.getline(tmp.GioiTinh, 5);
	cout << "Nam sinh " << endl;
	is >> tmp.NamSinh;
	cout << "Noi sinh " << endl;
	is.getline(tmp.NoiSinh, 100);
	cout << "Dia chi " << endl;
	is.getline(tmp.DiaChi, 100);
	return is;
}

class GiaoVien: public ConNguoi{
	private:
		Date NgayVaoTruong;
		char * ChuyenMon;
	public:
		GiaoVien():ConNguoi(){
			ChuyenMon = new char[30];
			strcpy(ChuyenMon, "");
		}
		GiaoVien(const GiaoVien& tmp):ConNguoi(tmp){
			NgayVaoTruong = tmp.NgayVaoTruong;
			ChuyenMon = new char[30];
			strcpy(ChuyenMon, tmp.ChuyenMon);
		
		}
		GiaoVien& operator = (const GiaoVien& tmp){

			NgayVaoTruong = tmp.NgayVaoTruong;
			delete [] ChuyenMon;
			ChuyenMon = new char[30];
			strcpy(ChuyenMon, tmp.ChuyenMon);
			return *this;
		};
		~GiaoVien();
		
		friend ostream& operator << (ostream& os, GiaoVien tmp);
		friend istream& operator >> (istream& is, GiaoVien& tmp);
};

GiaoVien::~GiaoVien(){
	delete [] ChuyenMon;
}

ostream& operator << (ostream& os, GiaoVien tmp){
	cout << tmp;
	os << "Ngay vao truong " << tmp.NgayVaoTruong;
	os << "Chuyen mon " << tmp.ChuyenMon;
	return os;
}

istream& operator >> (istream& is, GiaoVien& tmp){
	cin >> tmp;
	cout << "Ngay vao truong " << endl;
	is >> tmp.NgayVaoTruong;
	cout << "Chuyen mon " << endl;
	is.getline(tmp.ChuyenMon, 30);
	return is;
}

class SinhVien: public ConNguoi{
	private:
		int DiemVan;
		int DiemToan;
		int DiemNgoaiNgu;
	public:		
};

int main(){
	GiaoVien a;
	cin >> a;
	cout << a;
	return 0;
}

Đừng quan tâm tới lớp sinh viên.
Vấn đề là em khởi tạo được thuộc tính NamSinh trong lớp ConNguoi mà em không khởi tạo được thuộc tính NgayVaoTruong trong lớp GiaoVien em cũng khởi tạo như lớp ConNguoi mà không được. Có thánh nào pro vào hướng dẫn em với.

... viết 19:07 ngày 30/09/2018

Trong class hay struct Date bạn có overload operator << với >> không?

Nguyễn Trọng Phương viết 19:19 ngày 30/09/2018

Mình cũng tái định nghĩa lại >> vs << trong class Date nữa, và trong class Date mình có 4 hàm khởi tạo như vầy:
Date();
Date(int, int, int);
Date(const Date& tmp);
Date& operator = (const Date& tmp);

Nguyễn Trọng Phương viết 19:13 ngày 30/09/2018

mình có thể khởi tạo kiểu như thế này trong class ConNguoi : ConNguoi::ConNguoi():NamSinh(1,1,2000),
nhưng trong class GiaoVien thì mình không khởi tạo kiểu tương tự được như vầy: GiaoVien():ConNguoi():NgayVaoTruong(1,1,2000), như thế này thì lại không được. Không hiểu luôn.

... viết 19:15 ngày 30/09/2018

GiaoVien():ConNguoi():NgayVaoTruong(1,1,2000),

Mình nghĩ nên khởi tạo ở lớp GiaoVien như thế này

GiaoVien():ConNguoi(),NgayVaoTruong(1,1,2000)

dấu phẩy để liệt kê constructor, còn dấu hai chấm nó có ý nghĩa khác.

Nguyễn Trọng Phương viết 19:17 ngày 30/09/2018

afk cám ơn bạn nha. mà bạn cho mình hỏi sử dụng nhập xuất với tái định nghĩa có khác với mình tạo hàm riêng không.

... viết 19:18 ngày 30/09/2018

Chắc là không có gì khác ngoài việc dùng operator làm cho cú pháp ngắn gọn hơn.

Gió viết 19:15 ngày 30/09/2018
ostream& operator << (ostream& os, GiaoVien tmp){
	cout << tmp;
	os << "Ngay vao truong " &lt;&lt; tmp.NgayVaoTruong;
	os <<"Chuyen mon " &lt;&lt; tmp.ChuyenMon;
	return os;
}

Vấn đề là bạn đang overload <<, mà bạn lại sử dụng nó nên có lẽ bị lỗi .
Tương tư overload >>

Nguyễn Trọng Phương viết 19:11 ngày 30/09/2018

Lỗi là lỗi chổ nào nhỉ mình không hiểu lắm về overload >> vs << chỉ biết tạo ra rồi sử dụng ngắn hơn thôi.
Chẳng hạn như bây giờ mình có hàm void Nhap(); trong class ConNguoi thì mình sử dụng nó như thế nào trong class GiaoVien nhỉ .

... viết 19:18 ngày 30/09/2018

về vấn đề “đa hình” function có lẽ nên sử dụng virtual function.

Gió viết 19:10 ngày 30/09/2018
ConNguoi::~ConNguoi(){
	delete [] HoTen;
	delete [] GioiTinh;
	delete [] NoiSinh;
	delete [] NoiSinh;
}

Làm gì mà nhiều NoiSinh vậy

Nguyễn Trọng Phương viết 19:08 ngày 30/09/2018

Có lẽ nhầm bác ak

Nguyễn Trọng Phương viết 19:18 ngày 30/09/2018

Plzzzzz!
Em không nhập vào và xuất ra được. Ai pro chỉ em với.
ostream& operator << (ostream& os, GiaoVien tmp){
os << tmp;
os << "Ngay vao truong " << tmp.NgayVaoTruong;
os << "Chuyen mon " << tmp.ChuyenMon;
return os;
}

istream& operator >> (istream& is, GiaoVien& tmp){
is >> tmp;
cout << "Ngay vao truong " << endl;
is >> tmp.NgayVaoTruong;
is.ignore();
cout << "Chuyen mon " << endl;
is.getline(tmp.ChuyenMon, 30);
return is;
}

Gió viết 19:05 ngày 30/09/2018
ostream& operator &lt;&lt; (ostream& os, GiaoVien tmp){
	cout &lt;&lt; tmp; //<- Bỏ dòng này
	os &lt;&lt; "Ngay vao truong " &lt;&lt; tmp.NgayVaoTruong;
	os &lt;&lt; "Chuyen mon " &lt;&lt; tmp.ChuyenMon;
	return os;
}

istream& operator &gt;&gt; (istream& is, GiaoVien& tmp){
	cin &gt;&gt; tmp;  //<- Bỏ dòng này
	cout &lt;&lt; "Ngay vao truong " &lt;&lt; endl;
	is &gt;&gt; tmp.NgayVaoTruong;
	cout &lt;&lt; "Chuyen mon " &lt;&lt; endl;
	is.getline(tmp.ChuyenMon, 30);
	return is;
}
  • Như đã nói ở trên thì bạn chưa overload các toán tử nhập xuất mà lại sử dụng trong hàm overload thì không chạy dc.
Nguyễn Trọng Phương viết 19:12 ngày 30/09/2018

Bõ 2 dòng đó thì chỉ có thể nhập xuất trong phạm vi class GiaoVien còn class ConNguoi thì không nhập xuất được sau kì vậy ta. -_-

Bài liên quan
0