Con trỏ hoạt động như thế nào trong OOP?

Xin chào , cho em hỏi là khi con trỏ của lớp cơ sở tham chiếu đến các đối tượng của lớp dẫn xuất thì tại sao nó lại không truy cập được các hàm thành phần của lớp dẫn xuất ạ (có phải là do tính đóng gói không ạ) ? Và có cách nào để truy cập các hàm thành phần của lớp dẫn xuất trực tiếp hoặc gián tiếp từ con trỏ của lớp cơ sở không ạ ?

#include<iostream>
using namespace std;

class Media {
	private : 
		string name;
		long int price;
	public : 
		Media(string name, long int price);
		~Media(){
		}
		virtual void input();
		virtual void output();
};
Media::Media(string name, long int price){
	this->name = name;
	this->price = price;
}
void Media::input(){
	cout<<"Enter name : ";
	cin>>name;
	cout<<"Enter price : ";
	cin>>price;
}
void Media::output(){
	cout<<"Display name : "<<name<<endl;
	cout<<"Display price : "<<price<<endl;
}
class Book :public Media{
	private : 
		int page;
		string author;
	public : 
		Book(string name, long int price):Media(name, price){
			this->page = 0;
			this->author = "";
		}	
		void input();
		void output();
		Book operator>(Book &);
};
void Book::input(){
	Media::input();
	cout<<"Enter page : ";
	cin>>page;
	cout<<"Enter author : ";
	fflush(stdin);
	getline(cin, author);
}
void Book::output(){
	Media::output();
	cout<<"Display page : "<<page<<endl;
	cout<<"Display author : "<<author<<endl;
}
Book Book::operator>(Book &x){
	return (this->page > x.page) ? *this : x;
}
int main(){
	Media *p[3] ;
	for(i =0; i<3; i++){
		p[i] = new Book("name", 4500);
		cout<<"Nhap gia tri cua phan tu thu "<<i<<" : ";
		p[i]->input();
	}
	for(int i=0; i<3; i++){
		p[i] = new Book("name", 4500);
		for(int j=i; j<n; j++){
		    p[i]->operator>(p[j]);	  // không thể truy cập được hàm thầnh phần của lớp dẫn xuất
		}
	}
}

Là bạn “không hoạt động” chứ không phải do con trỏ. Bạn chưa ép về kiểu con (Book) thì sao nó hoạt động. Bạn khai báo mảng p là kiểu Media mà, mà bạn thấy trong Media có khai báo operator> không?

#include<iostream>
using namespace std;

class Media {
	private : 
		string name;
		long int price;
	public : 
		Media(string name, long int price);
		~Media(){
		}
		virtual void input();
		virtual void output();
};
Media::Media(string name, long int price){
	this->name = name;
	this->price = price;
}
void Media::input(){
	cout<<"Enter name : ";
	cin>>name;
	cout<<"Enter price : ";
	cin>>price;
}
void Media::output(){
	cout<<"Display name : "<<name<<endl;
	cout<<"Display price : "<<price<<endl;
}
class Book :public Media{
	private : 
		int page;
		string author;
	public : 
		Book(string name, long int price):Media(name, price){
			this->page = 0;
			this->author = "";
		}	
		void input();
		void output();
		Book operator>(Book &);
};
void Book::input(){
	Media::input();
	cout<<"Enter page : ";
	cin>>page;
	cout<<"Enter author : ";
	fflush(stdin);
	getline(cin, author);
}
void Book::output(){
	Media::output();
	cout<<"Display page : "<<page<<endl;
	cout<<"Display author : "<<author<<endl;
}
Book Book::operator>(Book &x){
	return (this->page > x.page) ? *this : x;
}
int main(){
	Media *p[3] ;
	for(int i =0; i<3; i++){
		p[i] = new Book("name", 4500);
		cout<<"Nhap gia tri cua phan tu thu "<<i<<" : ";
		p[i]->input();
	}
	for(int i=0; i<3; i++){
		p[i] = new Book("name", 4500);
		for(int j=i; j<3; j++){
		    ((Book*)p[i])->operator>(*(Book*)p[j]);	  // được chưa?
		}
	}
}

Mà đoạn trên bạn đang làm gì vậy? Chứ vòng lặp thứ 2 vô nghĩa lắm.

3 Likes

Em cảm ơn anh ! Vòng lặp thứ hai em làm là để so sánh các đối tượng Book của mảng.

= > Cái này đơn giản là vì thành phần đó không hề tồn tại ở lớp cơ sở thì không thể truy cập thôi. Ví dụ như

class A{
  int a;
  // Thì ở đây làm sao có thể truy cập thành phần `int b` ở đâu đó được?
};

=> Cái này có thể thông qua virtual function như các hàm inputoutput trong đoạn code của bạn.

Tiếp theo, về vấn đề trong code:

  1. Nếu làm như SITUVN, thì danh sách Media phải chỉ chứa toàn Book, mà nếu đã như vậy thì tại sao lại không lưu trong danh sách Book thay vì Media?
  2. Còn nếu danh sách Media có nhiều kiểu, thì có vấn đề như sau: giả sử có lớp Animal và 2 lớp Cat, Dog kế thừa Animal, vậy thì bây giờ có 1 danh sách các Animal, thì bạn làm sao so sánh Animal với Cat hay là so sánh CatDog?
5 Likes

Quên nhắc bạn, nên khai báo operator>Media.

2 Likes

Dạ , nhưng mà đề yêu cầu không khai báo operator> ở Media anh ạ.
Đề yêu cầu so sánh các đối tượng book thông qua toán tử operator> anh ơi

std::dynamic_cast<Book> thôi :slight_smile:

5 Likes

Bạn muốn hiểu sâu hơn thì có thể tìm kiếm từ khóa vtable.

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?