(一)C++對象模型和this指針
成員變量和成員函數分開存儲
- 空對象佔用內存爲1
每個空對象有個獨一無二的內存地址 - 非靜態成員變量,屬於類的對象上
- 靜態成員變量,不屬於類的對象上
- 非靜態成員函數,不屬於類的對象上
- 非靜態成員變量,屬於類的對象上
this指針概念
this指針指向被調用的成員函數所屬的對象
- 解決名稱衝突
- 返回對象本身*this
空指針可以調用成員函數
const 可以修飾成員函數
(二)友元
1.全局函數做友元
#include <iostream>
using namespace std;
class Building
{
friend void GoodGay(Building *building);
private:
string bedroom;
public:
string livingroom;
public:
Building()
{
bedroom="房間";
livingroom="客廳";
}
};
void GoodGay(Building *building)
{
cout<<"hello world"<<building->bedroom<<endl;
cout<<"hello world"<<building->livingroom<<endl;
}
int main()
{
Building build;
GoodGay(&build);
return 0;
}
2.類做友元
太難了
3.成員函數做友元
(三)C++運算符重載
(四)繼承(共性和個性)
1.class 子類:繼承方式 父類
2.繼承方式:
- 公共繼承
- 保護繼承
- 私有繼承
3.繼承的對象模型
子類繼承父類中全部的非靜態變量
private只是被隱藏了,但會繼承下去
4.構造和析構順序
構造先父類後子類,析構相反;
5.繼承同名成員處理方式(變量和函數)
訪問子類,直接訪問
訪問父類,加作用域
函數重載時,子類會隱藏父類
6.靜態成員處理方式(兩種訪問方式)
7.多繼承語法
8.菱形繼承
菱形繼承時,兩個父類具有相同的數據,需要加以作用域區分
#include <iostream>
using namespace std;
class Animal
{
public:
Animal()
{
cout<<"hello world"<<endl;
age=15;
};
int age;
};
class Sheep:public Animal{};
class Tuo:public Animal{};
class SheepTuo:public Sheep,public Tuo{};
int main()
{
SheepTuo s1;
s1.Sheep::age=50;
s1.Tuo::age=70;
cout<<"hello world"<<s1.Sheep::age<<endl;
cout<<"hello world"<<s1.Tuo::age<<endl;
return 0;
}
輸出
hello world
hello world
hello world50
hello world70
虛繼承解決菱形繼承的問題
#include <iostream>
using namespace std;
class Animal
{
public:
Animal()
{
cout<<"hello world"<<endl;
age=15;
};
int age;
};
//virtual關鍵字虛繼承,Animal稱爲虛基類
class Sheep:virtual public Animal{};
class Tuo:virtual public Animal{};
class SheepTuo:public Sheep,public Tuo{};
int main()
{
SheepTuo s1;
s1.Sheep::age=50;
s1.Tuo::age=70;
s1.age=1000;
cout<<"hello world "<<s1.Sheep::age<<endl;
cout<<"hello world "<<s1.Tuo::age<<endl;
cout<<"hello world "<<s1.age<<endl;
return 0;
}
輸出
hello world
hello world 1000
hello world 1000
hello world 1000
(五)多態
- 多態分爲兩類:
靜態多態:函數重載和運算符重載屬於靜態多態,複用函數名
動態多態:派生類和虛函數實現運行時多態 - 區別:
靜態多態:函數地址早綁定,編譯階段確定函數地址
動態多態:函數地址晚綁定,運行階段確定函數地址
#include <iostream>
using namespace std;
class Animal
{
public:
virtual void speak()
{
cout<<"Animal speak!"<<endl;
}
};
class Cat:public Animal
{
public:
void speak()
{
cout<<"Cat speak!"<<endl;
}
};
class Dog:public Animal
{
public:
void speak()
{
cout<<"Dog speak!"<<endl;
}
};
void dospeak(Animal &animal)
{
animal.speak();
}
int main()
{
Cat cat1;
dospeak(cat1);
return 0;
}
結果:
Cat speak!
- 條件
要有繼承關係
子類要重寫父類的虛函數 - 優點
代碼組織結構清晰
可讀性強
利於前期後期拓展和維護
- 純虛函數
virtual 返回值類型 函數名(參數列表)=0; - 類中有純虛函數,也叫抽象類
特點:
無法實例化對象
子類必須重寫抽象類中的純虛函數,否則子類也是抽象類
#include <iostream>
using namespace std;
class Animal
{
public:
virtual void dospeak()=0;
};
class Cat:public Animal
{
public:
virtual void dospeak()
{
cout<<"hello world"<<endl;
}
};
int main()
{
Animal *animal= new Cat;
animal->dospeak();
delete animal;
return 0;
}