詳解C++類型兼容性規(guī)則
一個公有派生類的對象在使用上可以被當作基類的對象,反之則禁止。具體表現(xiàn)在:
- 派生類的對象可以被賦值給基類對象。
- 派生類的對象可以初始化基類的引用。
- 指向基類的指針也可以指向派生類。
通過基類對象名、指針只能使用從基類繼承的成員
舉例:
1.派生類的對象可以被賦值給基類對象。這是一個總綱領,意味著在需要基類對象的地方,我們都可以用一個派生類對象來替代。
這會導致對象切片
#include <iostream>
#include <string>
// 基類
class Person {
public:
std::string name;
void introduce() {
std::cout << "我是一個人, 我的名字是 " << name << std::endl;
}
};
// 公有派生類
class Student : public Person {
public:
int studentID; // 派生類特有的成員
void study() { // 派生類特有的方法
std::cout << name << " 正在學習, 學號是 " << studentID << std::endl;
}
};
int main() {
Student stu;
stu.name = "張三";
stu.studentID = 101;
Person per;
per = stu; // 將派生類對象 stu 賦值給 基類對象 per
std::cout << "基類對象 per 的名字: " << per.name << std::endl;
per.introduce();
// per.studentID = 102; // 錯誤! per 是一個 Person 對象, 它沒有 studentID 成員。
// per.study(); // 錯誤! per 是一個 Person 對象, 它沒有 study() 方法。
}解釋:
當執(zhí)行 per = stu; 時,stu 對象中從 Person 繼承來的部分(也就是 name 成員)被拷貝到了 per 對象中。stu 對象自己獨有的成員(studentID)被完全“切掉”和丟棄了。因此,per 仍然是一個純粹的 Person 對象,它只知道 name,不知道任何關于 studentID 或 study() 的信息。
2.派生類的對象可以初始化基類的引用。這是實現(xiàn)多態(tài)的一種非常安全和常見的方式,不會發(fā)生對象切片。
#include <iostream>
#include <string>
// 基類
class Person {
public:
std::string name;
void introduce() {
std::cout << "我是一個人, 我的名字是 " << name << std::endl;
}
};
// 公有派生類
class Student : public Person {
public:
int studentID; // 派生類特有的成員
void study() { // 派生類特有的方法
std::cout << name << " 正在學習, 學號是 " << studentID << std::endl;
}
};
int main() {
Student stu;
stu.name = "李四";
stu.studentID = 102;
// 使用派生類對象 stu 來初始化一個基類的引用
Person& per_ref = stu;
std::cout << "通過基類引用訪問名字: " << per_ref.name << std::endl;
per_ref.introduce(); // 調用的是 Person 的方法
// per_ref.study(); // 錯誤! 雖然引用指向的是 Student 對象,但引用本身是 Person 類型,
// 只能訪問 Person 中定義的成員。
}解釋:
per_ref 是基類 Person 的一個引用,它直接綁定到了 stu 這個派生類對象上。內存中只有一個 stu 對象,沒有發(fā)生任何拷貝。per_ref 成為了 stu 對象的一個“別名”,但這個別名是 Person 類型的,所以它有一個受限的“視野”。
3.指向基類的指針也可以指向派生類。這是實現(xiàn)多態(tài)最核心、最靈活的方式,同樣不會發(fā)生對象切片。
#include <iostream>
#include <string>
// 基類
class Person {
public:
std::string name;
void introduce() {
std::cout << "我是一個人, 我的名字是 " << name << std::endl;
}
};
// 公有派生類
class Student : public Person {
public:
int studentID; // 派生類特有的成員
void study() { // 派生類特有的方法
std::cout << name << " 正在學習, 學號是 " << studentID << std::endl;
}
};
int main() {
Student stu;
stu.name = "王五";
stu.studentID = 103;
// 基類指針指向派生類對象
Person* per_ptr = &stu;
std::cout << "通過基類指針訪問名字: " << per_ptr->name << std::endl;
per_ptr->introduce(); // 調用的是 Person 的方法
// per_ptr->study(); // 錯誤! 指針類型是 Person*,它“看”不到 Student 類中新增的成員。
}解釋:
`per_ptr` 是一個 `Person` 類型的指針,它存儲了 `stu` 對象的內存地址。和引用一樣,它也只是提供了一個基類“視角”來觀察這個派生類對象。
到此這篇關于詳解C++類型兼容性規(guī)則的文章就介紹到這了,更多相關C++類型兼容性規(guī)則內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Visual Studio 2019配置OpenCV4.1.1詳細圖解教程
這篇文章主要介紹了Visual Studio 2019配置OpenCV4.1.1詳細圖解教程 ,需要的朋友可以參考下2020-02-02

