精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C++基礎知識之面向對象篇1

jf_78858299 ? 來源: 阿Q正磚 ? 作者: 阿Q ? 2023-03-02 09:49 ? 次閱讀

這兩期講完基本上面試遇到的相關問題就過了一半了,后續將STL和內存相關的補充完整,C++這塊的基本上就全部結束了,以后可能再也不會像現在這樣在這個方向投入過多時間,且行且珍惜啊,還是跟以前一樣,所有的總結都會有PDF版,如有需要自取。廢話不多說,發完這期,繼續整理STL去了。

1、C++函數模板

  • 模板的意義:對類型也可以進行參數化了。
  • 函數模板 《= 是不進行編譯的,因為類型不知道。
  • 模板的實例化 《= 函數調用點進行實例化。
  • 模板函數 《= 才是被編譯器所編譯的。
  • 模板類型參數。
  • 模板非類型參數。
  • 模板的實參推演 =》 可以根據用戶傳入的實參的類型,來推導模板類型。
  • 模板的特例化。
  • 函數模板、模板的特例化、非模板函數的重載關系。
  • 模板代碼是不能在一個文件中定義,在另外一個文件中使用的。
  • 模板代碼調用之前,一定要看到模板定義的地方,這樣的話,模板才能夠進行正常的實例化,產生能夠被編譯器編譯的代碼。
  • 所以,模板代碼都是放在頭文件當中的,然后在源文件當中直接進行#includ包含。

2、泛型算法

  • 泛型算法參數接收的都是迭代器!
  • 泛型函數 - 全局的函數 - 給所有容器用的
  • 泛型函數,有一套方式,,能夠統一的遍歷所有的容器的元素 - 迭代器。

3、拷貝賦值和移動賦值

  1. 拷貝賦值是通過拷貝構造函數來賦值,在創建對象時,使用同一類中之前創建的對象來初始化新創建的對象。
  2. 移動賦值是通過移動構造函數來賦值,二者的主要區別在于:
  • 拷貝構造函數的形參是一個左值引用,而移動構造函數的形參是一個右值引用。
  • 拷貝構造函數完成的是整個對象或變量的拷貝,而移動構造函數是生成一個指針指向源對象或變量的地址,接管源對象的內存,相對于大量數據的拷貝節省時間和內存空間。

4、虛函數、靜態綁定、動態綁定

虛函數表位于只讀數據段(.rodata) ,也就是C++內存模型中的常量區;而 虛函數則位于代碼段(.text) ,也就是C++內存模型中的代碼區。

一個類添加了虛函數,對這個類有什么影響?

  • 如果類里面定義了虛函數,那么編譯階段,編譯器給這個類類型產生一個唯一的vftable虛函數表,虛函數表中主要存儲的內容就是RTTI指針和虛函數的地址。當程序運行時,每一張虛表函數都會加載到內存的 .rodata區。
  • 一個類里面定義了虛函數,那么這個類定義的對象,其運行時,內存中開始部分,多存儲一個vfptr虛函數指針,指向相應類型的虛函數表vftable。一個類型定義的n個對象,它們的vfptr指向的都是同一張虛函數表。
  • 一個類里面虛函數的個數,不影響對象內存大小(vfptr),影響的是虛函數表的大小
  • 如果派生類中的方法,和基類繼承來的某個方法,返回值、函數名、參數列表都相同,而且基類的方法是virtual虛函數,那么派生類的這個方法,自動處理成虛函數。

靜態綁定和動態綁定:綁定指的是函數調用

  • 靜態綁定在編譯時期,綁定的是普通函數的調用 指令 :call Base::show(地址)
  • 動態綁定在運行時期,綁定的一定是虛函數的調用 指令:編譯的是call寄存器 運行時才知道

覆蓋:基類和派生類的方法,返回值、函數名以及參數列表都相同,而且基類的方法是虛函數,那么派生類的方法就是自動處理成虛函數,他們之間成為覆蓋關系。

在類內部添加一個虛擬函數表指針,該指針指向一個虛擬函數表,該虛擬函數表包含了所有的虛擬函數的入口地址,每個類的虛擬函數表都不一樣,在運行階段可以循環脈絡找到自己的函數入口。純虛函數相當于占位符,現在虛函數占一個位置由派生類實現后再把真正的函數指針填進去。

5、虛析構函數

  1. 哪些函數不能實現成虛函數?

虛函數依賴:

  • 虛函數能產生地址,存儲在vfptr當中
  • 對象必須存在(vfptr -> vftable -> 虛函數地址)

構造函數:沒有虛構造函數!!!

  • virtual+構造函數 NO!
  • 構造函數中(調用的任何函數,都是靜態綁定的)調用虛函數,也不會發生靜態綁定

派生類對象構造過程:先調用的是基類的構造函數,才調用派生類的構造函數。

static靜態成員方法 NO!

  1. 虛析構函數 析構函數調用的時候,對象是存在的!
  2. 什么時候把基類的析構函數必須實現成虛函數?

基類的指針(引用)指向堆上new出來的派生來對象的時候,delete pb(基類指針),它調用析構函數的時候,必須發生動態綁定,否則會導致派生類的析構函數無法調用

  1. 虛函數和動態綁定

問題:是不是虛函數的調用一定就是動態綁定?肯定不是!

在類的構造函數當中,調用虛函數,也是靜態綁定(構造函數中調用其他函數(虛),不會發生動態綁定)

靜態綁定 用對象本身調用虛函數,是靜態綁定

動態綁定:

  • 必須由指針調用虛函數
  • 必須由引用變量調用虛函數
  • 虛函數通過指針或者引用的調用,才發生動態綁定

6、如何解釋多態

  1. 靜態(編譯時期)的多態:函數重載、模板(函數模板和類模板)

    
    
    bool compare(int , int) { }
    bool cpmpare(double, double) { }
    compare(10,20); call compare_int_int  在編譯階段就確定好調用的函數版本
    compare(10.5, 20.5); call compare_double_double  在編譯階段就確定好調用的函數版本
    template<typename T>
    bool compare(T a, T b) { }
    compare<int>(10,20);  => int   實例化一個compare<int>
    compare(10.5 ,20.5);  => double  實例化一個 compare<double>
    
    
    
  2. 動態(運行時期)的多態:

在繼承結構中,基類指針(引用)指向派生類對象,通過指針(引用)調用同名覆蓋方法(虛函數),基類指針指向哪個派生類對象,就會調用哪個派生類對象的同名覆蓋方法,稱為多態。

pbase->show();

多態底層是通過動態綁定來實現的,pbase->訪問誰的vfptr ->繼續訪問誰的vftable -> 當然調用的是對應的派生類對象的方法了。

7、繼承

廣義的繼承有三種實現形式:

  1. 實現繼承:指使用基類的屬性和方法而無需額外編碼的能力。
  2. 可視繼承:子窗口使用父窗口的外觀和實現代碼。
  3. 接口繼承:僅使用屬性和方法,實現滯后到子類

好處:

  • 可以做代碼的復用
  • 在基類中給所有派生類提供統一的虛函數接口,讓派生類重寫,然后就可以使用多態了。

8、抽象類和普通類的區別

一般把什么類設計成抽象類?基類

//動物的基類 泛指 類 -> 抽象一個實體的類型

定義Animal的初衷,并不是讓Animal抽象某個實體的類型

  • string _name; 讓所有的動物實體類通過繼承Animal直接復用該屬性
  • 給所有的派生類保留統一的覆蓋/重寫接口

擁有純虛函數的類,叫抽象類!(Animal)

Animal a; NO!!!

抽象類不能再實例化對象了,但是可以定義指針和引用變量。

class Animal
{
public:
    Animal(string name) : _name(name) { }
    virtual void bark() = 0; //純虛函數
protected:
    string _name;
};
//以下是動物實體類
class Cat : public Animal
{
public:
    Cat(string name) : Animal(name) { }
    void bark() { cout << _name << "bark: miao miao!" << endl; }
};
class Dog :public Animal
{
public:
    Dog(string name):Animal(name) { }
    void bark() { cout << _name << "bark: wang wang!" << endl; }
};
class Pig :public Animal
{
    Pig(string name) :Animal(name) {        }
    void bark() { cout << _name << "bark: heng heng! " << endl; }
};
void bark(Animal* p)
{
    p->bark(); //Animal::bark虛函數,動態綁定了
}
int main()
{
    Cat cat("貓咪");
    Dog dog("二哈");
    Pig pig("佩奇");

    bark(&cat);
    bark(&dog);
    bark(&pig);


    return 0;
}

9、抽象類(有純虛函數的類) / 虛基類

virtual

  • 修飾成員方法的虛函數
  • 可以修飾繼承方式,是虛繼承。被虛繼承的類,稱作虛基類。
class A
{
public:
    virtual void func() { cout << "call A::func" << endl; }
    void operator delete(void* ptr)
{
        cout << "operator delete p:" << ptr << endl;
        free(ptr);
    }
private:
    int ma;
};
class B :virtual public A
{
public:
    void func() { cout << "call B::func" << endl; }
    void* operator new(size_t size)
{
        void* p = malloc(size);
        cout << "operator new p:" << p << endl;
        return p;
    }
private:
    int mb;
};


A a; 4個字節
B b; ma,mb  8個字節


int main()
{
    B b;
    A* p = &b;
    cout << "main p:" << p << endl;
    p->func();
    return 0;
}

基類指針指向派生類對象,永遠指向的是派生類基類部分數據的起始地址。

10、C++多繼承

菱形繼承的問題:派生類有多份間接基類的數據, 設計的問題

使用虛繼承

好處 :可以做更多代碼的復用。

C++語言級別提供的四種類型轉換方式:

  • const_cast:去掉常量屬性的一個類型轉換。
  • static_cast:提供編譯器認為安全的類型轉換(沒有任何聯系的類型之間的轉換就被否定)。
  • reinterpret_cast:類似于C風格的強制類型轉換。
  • dynamic_cast:主要用于在繼承結構中,可以支持RTTI類型識別的上下轉換。

11、函數對象

把有operator() 小括號運算符重載函數的對象,稱作函數對象或者仿函數。

  • 通過函數對象調用operator(),可以省略函數的調用開銷,比通過函數指針調用函數(不能夠inline內聯調用)效率高。
  • 因為函數對象是用類生成的,所以可以添加相關的成員變量,用來記錄函數對象使用時的信息
//函數對象
template

12、菱形繼承

多重繼承-菱形繼承的問題:

  • 好處:可以做更多代碼的復用。

基類被多個派生類用就需要是虛繼承,不然就會報錯。

基類需要被最后的派生類初始化。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C++
    C++
    +關注

    關注

    22

    文章

    2104

    瀏覽量

    73497
  • STL
    STL
    +關注

    關注

    0

    文章

    85

    瀏覽量

    18300
  • 面向對象
    +關注

    關注

    0

    文章

    64

    瀏覽量

    9978
收藏 人收藏

    評論

    相關推薦

    Labview 之面向對象編程。 里面有個例子 和視頻教程地址

    Labview 之面向對象編程。 里面有個例子 和視頻教程地址Labview 之面向對象編程。 里面有個例子 和視頻教程地址
    發表于 12-29 10:16

    C++ 面向對象多線程編程下載

    C++ 面向對象多線程編程下載
    發表于 04-08 02:14 ?70次下載

    C++語言基礎知識講解

    C++語言基礎知識講解,喜歡的朋友可以下載來學習。
    發表于 01-14 15:30 ?21次下載

    面向對象的程序設計(C++

    面向對象的程序設計(C++).面向對象的基本思想 C++
    發表于 03-22 14:40 ?0次下載

    C#入門教程之面向對象編程簡介的詳細資料概述

    本文檔的主要內容詳細介紹的是C#入門教程之面向對象編程簡介的詳細資料概述主要學習的目標是1.面向對象
    發表于 12-05 11:54 ?35次下載
    <b class='flag-5'>C</b>#入門教程<b class='flag-5'>之面向</b><b class='flag-5'>對象</b>編程簡介的詳細資料概述

    Visual C++教程之C++基礎知識介紹

    本文檔的主要內容詳細介紹的是Visual C++教程之C++基礎知識介紹主要內容包括了:1 類和對象,2 類的成員及特性,3 繼承和派生類
    發表于 02-15 15:59 ?9次下載
    Visual <b class='flag-5'>C++</b>教程之<b class='flag-5'>C++</b>的<b class='flag-5'>基礎知識</b>介紹

    C++語言和面向對象程序設計教程

    C++語言和面向對象程序設計代表了旨在使計算機問題解更加符合人的思維活動,是軟件開發方法的一場革命;面向對象建模和
    發表于 03-02 08:00 ?6次下載

    C/C++基礎知識匯總

    這是一五萬字的C/C++知識點總結,包括答案。
    的頭像 發表于 06-12 15:10 ?2352次閱讀

    C++基礎知識

    C++基礎知識
    的頭像 發表于 01-12 11:00 ?1358次閱讀
    <b class='flag-5'>C++</b><b class='flag-5'>基礎知識</b>

    C++基礎知識之面向對象2

    這兩期講完基本上面試遇到的相關問題就過了一半了,后續將STL和內存相關的補充完整,C++這塊的基本上就全部結束了,以后可能再也不會像現在這樣在這個方向投入過多時間,且行且珍惜啊,還是跟以前一樣,所有的總結都會有PDF版,如有需要自取。廢話不多說,發完這期,繼續整理STL去了。
    的頭像 發表于 03-02 09:53 ?389次閱讀

    C/C++之面向對象編程思想1

    C++作為一門在C和Java之間的語言,其既可以使用C語言中的高效指針,又繼承了Java中的面向對象編程思想,在去年編程語言排行榜上更是首次
    的頭像 發表于 03-30 15:14 ?622次閱讀
    <b class='flag-5'>C</b>/<b class='flag-5'>C++</b><b class='flag-5'>之面向</b><b class='flag-5'>對象</b>編程思想<b class='flag-5'>1</b>

    C/C++之面向對象編程思想2

    C++作為一門在C和Java之間的語言,其既可以使用C語言中的高效指針,又繼承了Java中的面向對象編程思想,在去年編程語言排行榜上更是首次
    的頭像 發表于 03-30 15:14 ?558次閱讀
    <b class='flag-5'>C</b>/<b class='flag-5'>C++</b><b class='flag-5'>之面向</b><b class='flag-5'>對象</b>編程思想2

    C/C++之面向對象編程思想3

    C++作為一門在C和Java之間的語言,其既可以使用C語言中的高效指針,又繼承了Java中的面向對象編程思想,在去年編程語言排行榜上更是首次
    的頭像 發表于 03-30 15:16 ?540次閱讀
    <b class='flag-5'>C</b>/<b class='flag-5'>C++</b><b class='flag-5'>之面向</b><b class='flag-5'>對象</b>編程思想3

    PyTorch教程3.2之面向對象的設計實現

    電子發燒友網站提供《PyTorch教程3.2之面向對象的設計實現.pdf》資料免費下載
    發表于 06-05 15:48 ?0次下載
    PyTorch教程3.2<b class='flag-5'>之面向</b><b class='flag-5'>對象</b>的設計實現

    C++語言基礎知識

    電子發燒友網站提供《C++語言基礎知識.pdf》資料免費下載
    發表于 07-19 10:58 ?7次下載