繼承中的構造函數和析構函數
繼承中的構造和析構順序
- 子類創建對象時,先調用父類的構造,然后調用自身構造
- 析構順序與構造順序相反
- 子類不會繼承父類的構造函數和析構函數
- 如果父類中沒有合適默認構造,那么子類可以利用初始化列表的方式顯示的調用父類的其它構造
#include<iostream>using namespace std;class Base
{
public:Base(){cout << "Base默認構造函數調用" << endl;}~Base(){cout << "Base的析構函數的調用" << endl;}
};
//子類會繼承父類的成員屬性,成員屬性
//但是 子類 不會繼承 父類 構造函數 和 析構函數
//只有父類自己知道如果構造和析構自己的屬性,而子類不知道class Son :public Base
{
public:Son(){cout << "Son默認構造函數的調用" << endl;}~Son(){cout << "Son的析構函數的調用" << endl;}
};class Base2
{
public:Base2(int a){this->m_A = a;cout << "有參構造函數調用" << endl;}int m_A;
};class Son2 :public Base2
{
public:Son2(int a) : Base2(10) //利用初始化列表方式 顯示調用 有參構造{}
};void test02()
{Son2 s2(1000);
}void test01()
{//Base b1;Son s1;
}int main()
{test01();system("pause");return 0;
}
注意:
- ?派生類的構造函數必須調用基類的構造函數初始化基類的那一部分成員。如果基類沒有默認的構造函 數,則必須在派生類構造函數的初始化列表階段顯示調用。
- 派生類的拷貝構造函數必須調用基類的拷貝構造完成基類的拷貝初始化。
- ?派生類的operator=必須要調用基類的operator=完成基類的復制。
- 派生類的析構函數會在被調用完成后自動調用基類的析構函數清理基類成員。因為這樣才能保證派生類 對象先清理派生類成員再清理基類成員的順序。
- 派生類對象初始化先調用基類構造再調派生類構造。
- 派生類對象析構清理先調用派生類析構再調基類的析構?
繼承中同名成員
繼承中的同名處理
- 成員屬性 直接調用先調用子類,如果想調用父類,需要作用域
- 成員函數 直接調用先調用子類,父類的所有版本都會被隱藏,除非顯示用作用域運算符去調用
#include<iostream>using namespace std;class Base
{
public:Base(){m_A = 100;}void fun(){cout << "Base func的調用" << endl;}void fun(int a){cout << "Base func(int a)的調用" << endl;}int m_A;
};class Son :public Base
{
public:Son(){m_A = 200;}void fun(){cout << "Son func的調用" << endl;}int m_A;
};void test01()
{Son s1;cout << s1.m_A << endl;//想調用 父類中的m_Acout << s1.Base::m_A << endl;//s1.fun(10);//調用父類的funcs1.Base::fun();
}
//如果父類和子類擁有同名的函數 屬性 子類不會覆蓋父類成員
//如果子類與父類的成員函數名稱相同 子類會把父類的所有同名版本都隱藏掉
//想調用父類的方法,必須加作用域int main()
{test01();system("pause");return 0;
}
?
注意:
1. 在繼承體系中基類和派生類都有獨立的作用域。
2. 子類和父類中有同名成員,子類成員將屏蔽父類對同名成員的直接訪問,這種情況叫隱藏,也叫重定 義。(在子類成員函數中,可以使用 基類::基類成員 顯示訪問)
3. 需要注意的是如果是成員函數的隱藏,只需要函數名相同就構成隱藏。
4. 注意在實際中在繼承體系里面最好不要定義同名的成員。
繼承中靜態成員
- 類似非靜態成員函數處理
- 如果想訪問父類中的成員,加作用域即可
#include<iostream>using namespace std;class Base
{
public:static void func(){cout << "Base func()" << endl;}static void func(int a){cout << "Base func(int a)" << endl;}static int m_A;
};
int Base::m_A = 10;class Son :public Base
{
public:static void func(){cout << "Son func()" << endl;}static int m_A;
};int Son::m_A = 20;
//靜態成員屬性 子類可以繼承下來
void test01()
{cout << Son::m_A << endl;//訪問父類的m_Acout << Base::m_A << endl;Son::func();//訪問父類中同名的成員函數Son::Base::func();
}int main()
{test01();system("pause");return 0;
}
注意:
- 靜態成員和非靜態成員都可以被繼承到派生類中
- 如果重新定義一個靜態成員函數,所有在基類中的其他重載函數會被隱藏
- 如果我們改變基類中一個函數的特征,所有使用該函數的基類版本都會被隱藏
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?