Lập trình C++ - Chuyển đổi kiểu
Chuyển đổi kiểu giữa lớp cơ sở và lớp dẫn xuất
Về mặt dữ liệu, một lớp dẫn xuất bao giờ cũng chứa toàn bộ dữ liệu của lớp cơ sở: Ta luôn tìm thấy lớp cơ sở trong lớp dẫn xuất, nhưng không phải bao giờ cũng tìm thấy lớp dẫn xuất trong lớp cơ sở. Do vậy:
- Có thể gán một đối tượng lớp dẫn xuất cho một đối tượng lớp cơ sở:
<Đối tượng lớp cơ sở> = <Đối tượng lớp dẫn xuất>; // Đúng
- Nhưng không thể gán một đối tượng lớp cơ sở cho một đối tượng lớp dẫn xuất:
<Đối tượng lớp dẫn xuất> = <Đối tượng lớp cơ sở>; // Không được
Ví dụ, ta có lớp Bus kế thừa từ lớp Car và: Bus myBus;
Car myCar; khi đó, phép gán:
myCar = myBus; // đúng thì chấp nhận được, nhưng phép gán:
myBus = myCar; // không được thì không chấp nhận được.
Lưu ý:
- Nguyên tắc chuyển kiểu này cũng đúng với các phép gán con trỏ: một con trỏ đối tượng lớp cơ sở có thể trỏ đến địa chỉ của một đối tượng lớp dẫn xuất. Nhưng một con trỏ đối tượng lớp dẫn xuất không thể trỏ đến địa chỉ một đối tượng lớp cơ sở.
- Nguyên tắc chuyển kiểu này cũng đúng với truyền đối số cho hàm: có thể truyền một đối tượng lớp dẫn xuất vào vị trí của tham số có kiểu lớp cơ sở. Nhưng không thể truyền một đối tượng lớp cơ sở vào vị trí một tham số có kiểu lớp dẫn xuất.
Ví dụ minh họa việc chuyển kiểu giữa các đối tượng của lớp cơ sở và lớp dẫn xuất.
#include<iostream>
#include<string>
using namespace std;
/* Định nghĩa lớp */
class Car {
private:
int speed; // Tốc độ
string mark; // Nhãn hiệu
float price; // Giá xe
public:
Car(int speed, string mark, float price);
void setSpeed(int); // Gán tốc độ cho xe
int getSpeed(); // Lấy tốc độ xe
void setMark(string); // Gán nhãn cho xe
string getMark(); // Lấy nhãn xe
void setPrice(float); // Gán giá cho xe
float getPrice(); // Lấy giá xe
void show(); // Hiển thị thông tin về xe
};
/* Khai báo phương thức bên ngoài lớp */
void Car::setSpeed(int speedIn) { // Gán tốc độ cho xe
speed = speedIn;
}
int Car::getSpeed() { // Lấy tốc độ xe
return speed;
}
void Car::setMark(string markIn) { // Gán nhãn cho xe
mark = markIn;
}
string Car::getMark() { // Lấy nhãn xe
return mark;
}
void Car::setPrice(float priceIn) { // Gán giá cho xe
price = priceIn;
}
float Car::getPrice() { // Lấy giá xe
return price;
}
/* Khai báo phương thức bên ngoài lớp */
Car::Car(int speed, string mark, float price) {
this->speed = speed;
this->mark = mark;
this->price = price;
}
void Car::show() { // Phương thức hiển thị xe
cout << "This is a " << mark << " having a speed of " << speed << "km/h and its price is $" << price << endl;
return;
}
/* Định nghĩa lớp Bus kế thừa từ lớp Car */
class Bus : public Car {
int label; // Số hiệu tuyến xe
public:
// Khởi tạo đủ tham số
Bus(int speed = 0, string mark = "", float price = 0, int lable = 0);
void setLabel(int); // Gán số hiệu tuyến xe
int getLabel(); // Đọc số hiệu tuyến xe
void show();
};
// Cài đặt lớp Bus
Bus::Bus(int speed, string mark, float price, int label) :Car(speed, mark, price) {
this->label = label;
}
// Định nghĩa nạp chồng phương thức
void Bus::show() { // Giới thiệu xe bus
cout << "This is a bus of type " << getMark() << ", on the line "
<< label << ", having a speed of " << getSpeed()
<< "km / h and its price is $" << getPrice() << endl;
return;
}
void Bus::setLabel(int label) { // Gán số hiệu tuyến xe
this->label = label;
}
int Bus::getLabel() { // Đọc số hiệu tuyến xe
return this->label;
}
// Hàm main, chuong trình chính
int main() {
Car myCar(100, "Ford", 3000); // Biến đối tượng lớp Car
Bus myBus(80, "Mercedes", 5000, 27);// Biến đối tượng lớp Bus
cout << "Gioi thieu xe o to lan 1:" << endl;
myCar.show();
cout << "Gioi thieu xe o to lan 2:" << endl;
myCar = myBus;
myCar.show();
cout << "Gioi thieu xe bus : " << endl;
myBus.show();
system("pause");
return 0;
}
Kết quả:
his is a Ford having a speed of 100km/h and its price is $3000
Gioi thieu xe o to lan 2:
This is a Mercedes having a speed of 80km/h and its price is $5000
Gioi thieu xe bus :
This is a bus of type Mercedes, on the line 27, having a speed of 80km / h and its price is $5000
Ở thông báo thứ nhất, đối tượng myCar gọi phương thức show() của lớp Car với các dữ liệu được khởi đầu cho myCar: (100, “Ford”, 3000). Ở thông báo thứ hai, myCar gọi phương thức show() của lớp Car, nhưng với dữ liệu vừa được gán từ đối tượng myBus: (80, “Mercedes”, 5000). Ở thông báo thứ ba, myBus gọi phương thức show() của lớp Bus với các dữ liệu của myBus: (80, “Mercedes”, 5000, 27).