ROS基礎知識學習筆記(4)—C++類和對象(2)

(一)C++對象模型和this指針

成員變量和成員函數分開存儲

  1. 空對象佔用內存爲1
    每個空對象有個獨一無二的內存地址
  2. 非靜態成員變量,屬於類的對象上
  3. 靜態成員變量,不屬於類的對象上
  4. 非靜態成員函數,不屬於類的對象上
  5. 非靜態成員變量,屬於類的對象上

this指針概念

this指針指向被調用的成員函數所屬的對象

  1. 解決名稱衝突
  2. 返回對象本身*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.繼承方式:

  1. 公共繼承
  2. 保護繼承
  3. 私有繼承

在這裏插入圖片描述

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

(五)多態

  1. 多態分爲兩類:
    靜態多態:函數重載和運算符重載屬於靜態多態,複用函數名
    動態多態:派生類和虛函數實現運行時多態
  2. 區別:
    靜態多態:函數地址早綁定,編譯階段確定函數地址
    動態多態:函數地址晚綁定,運行階段確定函數地址
#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!
  1. 條件
    要有繼承關係
    子類要重寫父類的虛函數
  2. 優點
    代碼組織結構清晰
    可讀性強
    利於前期後期拓展和維護
    在這裏插入圖片描述
  3. 純虛函數
    virtual 返回值類型 函數名(參數列表)=0;
  4. 類中有純虛函數,也叫抽象類
    特點:
    無法實例化對象
    子類必須重寫抽象類中的純虛函數,否則子類也是抽象類
#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;
}

b站鏈接:多態案例1
b站鏈接:多態案例2

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章