author:&Carlton
tag:C++
topic:【C++】繼承基礎知識及簡單應用,使用reportSingleClassLayout(在Visual Studio開發(fā)人員命令提示窗口)查看派生類詳細信息
website:黑馬程序員C++
date:2023年7月22日
目錄
概要
繼承規(guī)則
對象模型
構造析構順序
同名與靜態(tài)同名成員
多繼承
菱形繼承
VS開發(fā)人員命令操作提示窗口
概要
?
? ? ? ? 繼承是C++面向對象程序設計的三大特性之一(封裝,繼承,多態(tài)),既能有效利用已定義好的類,又允許添加之前定義的類中沒有的代碼,有效縮減代碼量,使得程序更加簡潔。
繼承規(guī)則
? ? ? ? class 子類名 : 繼承方式 父類名 { };
? ? ? ? 繼承方式有public,protected,private
對象模型
? ? ? ? 父類所有成員都繼承,只是根據(jù)繼承方式不同繼承得到的成員訪問權限也相應改變:
? ? ? ?(父類的私有成員子類繼承,但均無法訪問,需要聲明友元,以下說明不包括父類私有成員)
????????①公開繼承public: 訪問權限相應繼承
? ? ? ? ②保護繼承protected: 全定為protected
? ? ? ? ③私有繼承private: 全部變?yōu)閜rivate
? ? ? ? 注:成員包括屬性和函數(shù)
? ? ? ? 子類對象模型結構(具體操作步驟在本文最后一小節(jié)說明):
? ? ? ? 說明子類繼承父類所有成員的例子:
#include <iostream>
using namespace std;
class Base
{
public:
int m_a;
protected:
int m_b;
private:
int m_c;
};
class Son:public Base
{
public:
int m_d;
};
void test01()
{
Son s1;
cout << sizeof(s1) << endl;
}
int main()
{
test01();
return 0;
}
構造析構順序
? ? ? ? 先構造父類,然后構造子類,析構順序與構造順序相反。
????????
源代碼:
#include <iostream>
using namespace std;
class Base
{
public:
Base()
{
cout << "Base的構造函數(shù)" << endl;
}
~Base()
{
cout << "Base的析構函數(shù)" << endl;
}
};
class Son :public Base
{
public:
Son()
{
cout << "Son的構造函數(shù)" << endl;
}
~Son()
{
cout << "Son的析構函數(shù)" << endl;
}
};
void test01()
{
Son s1;
}
int main()
{
test01();
return 0;
}
程序運行結果:
同名與靜態(tài)同名成員
? ? ? ? 需要添加作用域,對于靜態(tài)成員還能通過類訪問。
?????????Son::Base::m_b << endl;?? ?
????????與Base::m_b含義不同,這里是在子類Son中訪問父類Base作用域下的m_b靜態(tài)成員變量
#include <iostream>
using namespace std;
class Base
{
public:
Base():m_a(100)//父類的初始化為100
{
}
int m_a;
void func()
{
cout << "Base-func()" << endl;
}
void func(int a)
{
cout << "Base-func(a)" << endl;
}
//子類有同名的成員函數(shù)時父類的成員函數(shù)被隱藏,無法直接使用占位參數(shù)區(qū)分,還是需要添加作用域區(qū)分
static int m_b;
};
//靜態(tài)成員變量類內聲明,類外定義初始化
int Base::m_b = 100;
class Son:public Base
{
public:
Son():m_a(200)//子類的初始化為200
{
}
void func()
{
cout << "Son-func()" << endl;
}
int m_a;//有同名成員
static int m_b; //有靜態(tài)同名成員
};
int Son::m_b = 200;
void test01()
{
Son s1;
cout << "子類m_a:" << s1.m_a << endl;
cout << "父類m_a:" << s1.Base::m_a << endl; //添加作用域
s1.func();
s1.Base::func(); //添加作用域
s1.Base::func(10);
//通過對象訪問靜態(tài)成員
cout << "子類m_b:" << s1.m_b << endl;
cout << "父類m_b:" << s1.Base::m_b << endl;
//通過類訪問靜態(tài)成員
cout << "子類m_b:" << Son::m_b << endl;
cout << "父類m_b:" << Son::Base::m_b << endl; //與Base::m_b含義不同,這里是在子類Son中訪問父類Base作用域下的m_b靜態(tài)成員變量
}
int main()
{
test01();
return 0;
}
多繼承
class 子類名 : 繼承方式 父類名1,繼承方式 父類名2,……{ } ;
? ? ? ? 多繼承可能會帶來同名成員的問題,但在實際開發(fā)過程中這塊代碼可能由幾個人一起做,如果大量使用多繼承則出現(xiàn)同名成員問題時尋找作用域會很麻煩。
源代碼
#include <iostream>
using namespace std;
class Base1
{
public:
int m_a;
};
class Base2
{
public:
int m_b;
};
class Son :public Base1, public Base2 //繼承Base1和Base2
{
int m_c;
int m_d;
};
void test01()
{
cout << "sizeof(Son):" << sizeof(Son) << endl;
}
int main()
{
test01();
return 0;
}
多繼承對象模型結構(具體操作步驟見本文最后一節(jié)):
菱形繼承
? ? ? ? 菱形繼承:A被B、C繼承,D繼承B、C
????????解決菱形繼承的兩個問題:①二義性矛盾 ②資源浪費
????????①二義性矛盾:“孫子不知道從父1那訪問爺爺?shù)臇|西還是從父2那里訪問”
????????②資源浪費:無論從父1還是從父2,得到的東西是一樣的,不需要得到兩次
? ? ? ? 解決方法:
? ? ? ? ①添加作用域
? ? ? ? ②使用關鍵字virtual虛繼承
源代碼:
#include <iostream>
#include <string>
using namespace std;
/*
* 解決菱形繼承的兩個問題:①二義性矛盾 ②資源浪費
* ①二義性矛盾:“孫子不知道從父1那訪問爺爺?shù)臇|西還是從父2那里訪問”
* ②無論從父1還是從父2,得到的東西是一樣的,不需要得到兩次
*/
class School
{
public:
School():m_slogan("厚德載物,格物致知")
{
}
string m_slogan;
};
class Teacher1 :virtual public School {}; //加關鍵字virtual,虛繼承
class Teacher2 :virtual public School {};
class Student :public Teacher1, public Teacher2 {};
void test01()
{
Student s1;
//cout << s1.m_slogan << endl; //有二義性錯誤,m_slogan是Teacher1的還是Teacher2的
cout << s1.Teacher1::m_slogan << endl; //通過作用域解決第一個問題:二義性錯誤
cout << s1.Teacher2::m_slogan << endl;
cout << s1.m_slogan << endl; //使用virtual虛繼承可以不加作用域,都通過虛擬指針指向基類School的m_slogan,是同一個成員變量
}
int main()
{
test01();
return 0;
}
對象模型結構(具體操作步驟見本文最后一節(jié)):
使用虛繼承前:
?
使用虛繼承后:
vbtable:虛基類表
vb:virtual base?虛基類
ptr:pointer 指針
數(shù)字代表位移量
VS開發(fā)人員命令操作提示窗口
系統(tǒng)菜單里找到:
跳轉盤符:
?
鎖定文件路徑(包含源文件的上一級目錄):
?
應用:
? ? ? ? ①查看該文件路徑下文件情況
? ?
?
? ? ? ? ②查看類對象模型結構
文章來源:http://www.zghlxwxcb.cn/news/detail-602893.html
歡迎指正與分享,謝謝!文章來源地址http://www.zghlxwxcb.cn/news/detail-602893.html
到了這里,關于【C++】繼承基礎知識及簡單應用,使用reportSingleClassLayout(在Visual Studio開發(fā)人員命令提示窗口)查看派生類詳細信息的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!