日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

笔记②:牛客校招冲刺集训营---C++工程师(面向对象(友元、运算符重载、继承、多态) -- 内存管理 -- 名称空间、模板(类模板/函数模板) -- STL)

發(fā)布時(shí)間:2023/12/8 c/c++ 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 笔记②:牛客校招冲刺集训营---C++工程师(面向对象(友元、运算符重载、继承、多态) -- 内存管理 -- 名称空间、模板(类模板/函数模板) -- STL) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

0618

C++工程師

  • 第5章 高頻考點(diǎn)與真題精講
    • 5.1 指針 & 5.2 函數(shù)
    • 5.3 面向?qū)ο?#xff08;和5.4、5.5共三次直播課)
      • 5.3.1 - 5.3.11
      • 5.3.12-14 友元
        • 友元全局函數(shù)
        • 友元類
        • 友元成員函數(shù)
        • 友元的注意事項(xiàng)
      • 5.3.15-23 運(yùn)算符重載 -->靜態(tài)多態(tài)
        • 運(yùn)算符 + = == != ++ () << 重載
        • ☆☆☆指針運(yùn)算符重載(* 和 ->)(寫(xiě)個(gè)智能指針類)
        • 運(yùn)算符重載的應(yīng)用:封裝字符串類
      • 5.3.24 類的自動(dòng)類型轉(zhuǎn)換和強(qiáng)制類型轉(zhuǎn)換(關(guān)鍵字`explicit`)
      • 5.3.25-34 繼承
        • 繼承的概念、好處、弊端
        • 繼承的基本語(yǔ)法
        • protected訪問(wèn)權(quán)限
        • 繼承中的對(duì)象模型(成員變量和成員函數(shù)分開(kāi)存儲(chǔ))
        • 繼承中的構(gòu)造和析構(gòu)順序
        • 訪問(wèn)繼承中的 非靜態(tài) 同名 成員
        • 訪問(wèn)繼承中的 靜態(tài) 同名 成員
        • 總結(jié):如何訪問(wèn)繼承中的同名成員(靜態(tài)成員和非靜態(tài)成員)
        • 多繼承/多重繼承
        • 菱形繼承-->虛繼承、虛基類☆☆☆
        • 虛繼承的實(shí)現(xiàn)原理
      • 5.3.35-38 多態(tài)(一般是指動(dòng)態(tài)多態(tài))
        • 靜態(tài)聯(lián)編和動(dòng)態(tài)聯(lián)編(靜態(tài)多態(tài)和動(dòng)態(tài)多態(tài))
        • 虛函數(shù)的原理(多態(tài)的底層原理)
        • 多態(tài)案例(開(kāi)閉原則:對(duì)擴(kuò)展進(jìn)行開(kāi)放,對(duì)修改進(jìn)行關(guān)閉)
        • 純虛函數(shù) --> 抽象類
        • 虛析構(gòu)和純虛析構(gòu)(解決 調(diào)用不到子類析構(gòu)函數(shù) 的問(wèn)題)
      • C++面試寶典-->第一章-->1.3 面向?qū)ο?/li>
    • 5.6 內(nèi)存管理①(結(jié)合計(jì)算機(jī)操作系統(tǒng)筆記)
      • 1.重定位(地址轉(zhuǎn)換:邏輯地址-->物理地址)
      • 2.交換技術(shù)
      • 3.分段(將各段分別放入內(nèi)存)
      • 4.分頁(yè)(從連續(xù)到離散)
    • 5.7 內(nèi)存管理②(結(jié)合計(jì)算機(jī)操作系統(tǒng)筆記)
      • 5.段頁(yè)式管理 和 虛擬內(nèi)存(虛擬地址空間/虛擬內(nèi)存地址)
      • 6.虛擬內(nèi)存和段頁(yè)式存儲(chǔ)管理知識(shí)補(bǔ)充
        • 參考鏈接1
        • 參考鏈接2
        • 參考鏈接3
          • 1.如何將段和頁(yè)結(jié)合在一起
          • 2.段頁(yè)結(jié)合時(shí)進(jìn)程對(duì)內(nèi)存的使用
          • 看個(gè)例子(邏輯地址、虛擬地址、物理地址)
      • 虛擬內(nèi)存和虛擬存儲(chǔ)器的區(qū)別?
        • 參考鏈接4、5
      • 7.(5和6的)總結(jié)☆☆☆☆☆
        • 7.1 虛擬內(nèi)存的提出是為了解決什么問(wèn)題?
        • 7.2 虛擬內(nèi)存的原理解釋
        • 7.3 分頁(yè)和頁(yè)表
        • 7.4 虛擬內(nèi)存地址(邏輯地址)-->物理地址 (快表、缺頁(yè)中斷)
        • 7.5 虛擬內(nèi)存的功能
        • 7.6 段頁(yè)式內(nèi)存管理與虛擬內(nèi)存☆☆☆
      • C++面試寶典--> 1.2 C++內(nèi)存 和 第2章 操作系統(tǒng)
    • 5.7 名稱空間、模板
      • 補(bǔ)充:內(nèi)存對(duì)齊/字節(jié)對(duì)齊
      • 名稱空間
        • 作用域解析運(yùn)算符(兩個(gè)冒號(hào)`::`)
        • 名稱空間
        • using聲明和using編譯指令
      • 模板
        • 函數(shù)模板
          • ①函數(shù)模板語(yǔ)法
          • ②函數(shù)模板和普通函數(shù)的區(qū)別
          • ③函數(shù)模板調(diào)用規(guī)則
          • ④模板實(shí)現(xiàn)機(jī)制及局限性
        • 類模板
          • ①類模板基礎(chǔ)語(yǔ)法
          • ②類模板中成員函數(shù)的創(chuàng)建時(shí)機(jī)
          • ③類模板做函數(shù)參數(shù)
          • ④類模板派生類
          • ⑤類模板成員函數(shù)類內(nèi)實(shí)現(xiàn)
          • ⑥類模板成員函數(shù)類外實(shí)現(xiàn)
          • ⑦類模板分文件編寫(xiě)(類模板文件 .hpp)
          • ⑧模板類碰到友元函數(shù)
          • ⑨模板案例---數(shù)組類封裝
    • 5.8 STL(標(biāo)準(zhǔn)模板庫(kù))
      • 總結(jié) 常用容器的**排序**的區(qū)別:
        • 0.自定義排序規(guī)則的實(shí)現(xiàn)方式
        • 1.vector容器,deque容器;&& 2.list容器
        • 3.set容器,map容器:
        • 4.匯總
      • 函數(shù)對(duì)象 & 謂詞
        • 內(nèi)建函數(shù)對(duì)象
      • STL—常用算法
    • 5.9 C++新特性

第5章 高頻考點(diǎn)與真題精講

5.1 指針 & 5.2 函數(shù)

5.3 面向?qū)ο?#xff08;和5.4、5.5共三次直播課)

5.3.1 - 5.3.11

見(jiàn)筆記①:牛客校招沖刺集訓(xùn)營(yíng)—C++工程師

5.3.12-14 友元

友元分為三種:

  • 友元全局函數(shù)
  • 友元成員函數(shù)
  • 友元類

友元的目的就是讓一個(gè) 函數(shù)或者類 能夠訪問(wèn)另一個(gè)類中私有成員,關(guān)鍵字是 friend。重載<<運(yùn)算符時(shí),會(huì)用到友元。

友元全局函數(shù)

一個(gè)全局函數(shù)想訪問(wèn)一個(gè)類中的私有成員變量,那么就把這個(gè)全局函數(shù)設(shè)置為這個(gè)類的友元(friend),就可以訪問(wèn)了。

友元類

一個(gè)好朋友類想訪問(wèn)Building類中的私有成員變量,那么就把好朋友類設(shè)置為Building類的友元(friend),就可以訪問(wèn)了。

友元成員函數(shù)

好朋友類的成員函數(shù)visit()訪問(wèn)另一類的對(duì)象的私有成員變量:

成員函數(shù)visit()在類外實(shí)現(xiàn):

Building類中把GoodFriend類的成員函數(shù)visit()設(shè)置為友元,就可以訪問(wèn)自己的m_BedRoom屬性;
但GoodFriend類的成員函數(shù)visit1()沒(méi)被設(shè)置為友元,所以還是無(wú)法訪問(wèn)到自己的m_BedRoom屬性。

友元的注意事項(xiàng)

友元關(guān)系:
1.不能被繼承; 2.是單向的; 3.不具有傳遞性。

5.3.15-23 運(yùn)算符重載 -->靜態(tài)多態(tài)

運(yùn)算符 + = == != ++ () << 重載

C++筆記10:運(yùn)算符重載
概念:
對(duì)已有的運(yùn)算符重新進(jìn)行定義,賦予其另一種功能,以適應(yīng)不同的數(shù)據(jù)類型。
例如:加號(hào)運(yùn)算符重載的作用就是實(shí)現(xiàn)兩個(gè)自定義數(shù)據(jù)類型(類)相加的運(yùn)算

實(shí)現(xiàn)的方式有兩種:

  • 利用成員函數(shù)重載
  • 利用全局函數(shù)重載

C++筆記10:運(yùn)算符重載中實(shí)現(xiàn)了:

  • 加號(hào)運(yùn)算符(+)重載
  • 左移運(yùn)算符(<<)重載
    改進(jìn)
  • 遞增運(yùn)算符(++)重載(前置++ 和 后置++)
  • 賦值運(yùn)算符(=)重載
    如果類的成員變量在堆區(qū),做賦值操作時(shí)就會(huì)出現(xiàn)深拷貝與淺拷貝問(wèn)題。
  • 關(guān)系運(yùn)算符重載(== 和 !=)
  • 函數(shù)調(diào)用運(yùn)算符()重載—仿函數(shù)(在STL中用的比較多)
運(yùn)算符成員函數(shù)實(shí)現(xiàn)全局函數(shù)實(shí)現(xiàn)備注
加號(hào)運(yùn)算符(+)重載Students operator+(const Students& stu){}friend Students operator+(const Students& stu1, const Students& stu2){}
左移運(yùn)算符(<<)重載friend ostream& operator<<(ostream& cout, const Students& stu){}//可以實(shí)現(xiàn)連續(xù)cout輸出
遞增運(yùn)算符(++)重載前置++:Students& operator++(){}
后置++:Students operator++(int){}//這個(gè)int是為了和前置++形成重載,以通過(guò)編譯,int本身沒(méi)啥用
前置++:friend Students& operator++(Students& stu){}
后置++:friend Students operator++(Students& stu,int){}//這個(gè)int是為了和前置++形成重載,以通過(guò)編譯,int本身沒(méi)啥用
關(guān)系運(yùn)算符(== 和 !=)重載bool operator==(Students& stu) {}friend bool operator==(const Students& stu1, const Students& stu2){}
賦值運(yùn)算符(=)重載void operator=(const Person& p){}
升級(jí)版:Person& operator=(const Person& p){}//可以實(shí)現(xiàn)連續(xù)賦值
函數(shù)調(diào)用運(yùn)算符()重載也叫仿函數(shù)

(以上是筆記中復(fù)制來(lái)的內(nèi)容)

☆☆☆指針運(yùn)算符重載(* 和 ->)(寫(xiě)個(gè)智能指針類)

(視頻課從01:32:10開(kāi)始)
指針的操作就是解引用*和箭頭->,所以就是重載這兩個(gè)運(yùn)算符。

示例:

#include<iostream> using namespace std;class Person{ public:Person(int age){cout << "Person的構(gòu)造函數(shù)" << endl;m_Age = age;}//輸出成員信息:void showAge(){cout << "m_Age = " << this->m_Age << endl;}~Person(){cout << "Person的析構(gòu)函數(shù)" << endl;} private:int m_Age; };//智能指針類: class SmartPointer{ public://重載箭頭運(yùn)算符->Person* operator->(){return this->m_Person;}//重載解引用運(yùn)算符*Person& operator*(){return *m_Person;}SmartPointer(Person* p){cout << "SmartPointer的構(gòu)造函數(shù)" << endl;m_Person = p;}~SmartPointer(){cout << "SmartPointer析構(gòu)函數(shù)" << endl;if(this->m_Person != nullptr){delete this->m_Person;this->m_Person == nullptr;}} //private:Person* m_Person;//內(nèi)部維護(hù)的Person的指針 };int main(){Person* p = new Person(30);p->showAge();(*p).showAge();//正常應(yīng)該執(zhí)行下面這行,如果忘了就會(huì)造成內(nèi)存泄漏,所以就用下面的智能指針類//delete p;cout << "=================================" << endl;//智能指針類就是把p替換成了sp,并且在其析構(gòu)函數(shù)中將new的內(nèi)容delete掉,這樣就解決了可能造成的內(nèi)存泄漏問(wèn)題SmartPointer sp(p);sp->showAge();//相當(dāng)于sp.operator->()->showAge(); 其中sp.operator->()就相當(dāng)于psp.operator->()->showAge();//編譯器會(huì)把sp.operator->()->showAge()優(yōu)化成sp->showAge();(*sp).showAge();//相當(dāng)于sp.operator*().showAge();其中sp.operator*()相當(dāng)于*psp.operator*().showAge();//編譯器會(huì)把sp.operator*().showAge()優(yōu)化成(*sp).showAge();return 0;}

編譯運(yùn)行:

Person的構(gòu)造函數(shù) m_Age = 30 m_Age = 30 ================================= SmartPointer的構(gòu)造函數(shù) m_Age = 30 m_Age = 30 m_Age = 30 m_Age = 30 SmartPointer析構(gòu)函數(shù) Person的析構(gòu)函數(shù)

運(yùn)算符重載的應(yīng)用:封裝字符串類

視頻課:點(diǎn)這里

5.3.24 類的自動(dòng)類型轉(zhuǎn)換和強(qiáng)制類型轉(zhuǎn)換(關(guān)鍵字explicit)

被explicit修飾的構(gòu)造函數(shù)不能用于自動(dòng)類型轉(zhuǎn)換(隱式類型轉(zhuǎn)換)。

示例:

#include <iostream> using namespace std;class MyString { public:// 被explicit修飾的構(gòu)造函數(shù)不能用于自動(dòng)類型轉(zhuǎn)換(隱式類型轉(zhuǎn)換)explicit MyString(int len) {cout << "MyString有參構(gòu)造MyString(int len)..." << endl;}//explicit MyString(const char* str) {cout << "MyString有參構(gòu)造MyString(const char* str)..." << endl;}// 轉(zhuǎn)換函數(shù):轉(zhuǎn)換成doubleoperator double() {// 業(yè)務(wù)邏輯return 20.1;}};// 類的自動(dòng)類型轉(zhuǎn)換和強(qiáng)制類型轉(zhuǎn)換 /*如果我們想讓類對(duì)象轉(zhuǎn)換成基本類型的數(shù)據(jù),我們需要在類中添加轉(zhuǎn)換函數(shù)1.轉(zhuǎn)換函數(shù)必須是類方法2.轉(zhuǎn)換函數(shù)不能指定返回類型3.轉(zhuǎn)換函數(shù)不能有參數(shù) */ int main() {// 基本內(nèi)置數(shù)據(jù)類型的自動(dòng)類型轉(zhuǎn)換和強(qiáng)制類型轉(zhuǎn)換long count = 8;double time = 10;int size = 3.14;cout << count << endl; //8cout << time << endl; //10cout << size << endl; //3double num = 20.3;cout << num << endl; //20.3// 強(qiáng)制轉(zhuǎn)換成int類型的數(shù)據(jù)int num1 = (int)num; int num2 = int(num);cout << num1 << endl; //20cout << num2 << endl; //20MyString str = "hello"; //// MyString str = MyString("hello");// MyString str1 = 10; //不能通過(guò)隱式類型轉(zhuǎn)換創(chuàng)建對(duì)象了MyString str1 = MyString(10);// 類的強(qiáng)制類型轉(zhuǎn)換double d = str1;cout << d << endl; //20.1double d1 = double(str);double d2 = (double)str;cout << d1 << endl; //20.1cout << d2 << endl; //20.1return 0; }

結(jié)果:

8 10 3 20.3 20 20 MyString有參構(gòu)造MyString(const char* str)... MyString有參構(gòu)造MyString(int len)... 20.1 20.1 20.1

5.3.25-34 繼承

繼承的概念、好處、弊端

繼承是面向?qū)ο蟮囊淮筇卣鳌?/p>

繼承好處:

  • 提高代碼的復(fù)用性;
  • 提高代碼的維護(hù)性(方便維護(hù));
  • 讓類與類之間產(chǎn)生了關(guān)系,是(動(dòng)態(tài))多態(tài)的前提。

繼承的弊端:

  • 類的耦合性增加了

開(kāi)發(fā)的原則是:高內(nèi)聚,低耦合
內(nèi)聚:自己完成一件事的能力;
耦合:類和類之間的關(guān)系。

繼承的基本語(yǔ)法

繼承的語(yǔ)法:

class 子類:繼承方式 父類{ ... };例如: class dogs: public Animals { ... };

繼承方式分為public,protected,private,即公共繼承,保護(hù)繼承,私有繼承

注意:
如果不寫(xiě)繼承方式,默認(rèn)是私有繼承

protected訪問(wèn)權(quán)限

三種權(quán)限:

  • public: 公共的訪問(wèn)權(quán)限,被修飾的成員在類內(nèi)和類外都能夠被訪問(wèn);
  • protected: 受保護(hù)的訪問(wèn)權(quán)限,如果沒(méi)有繼承關(guān)系,就和private的特點(diǎn)一樣;
  • privated: 私有的訪問(wèn)權(quán)限,被修飾的成員只能在類內(nèi)被訪問(wèn),在類外不能夠被訪問(wèn);

在繼承關(guān)系中,父類中的protected修飾的成員,子類中可以直接訪問(wèn),但在類外的其他地方不能訪問(wèn)。

成員變量一般使用privated私有訪問(wèn)控制,不要使用protected受保護(hù)的訪問(wèn)控制;
成員方法如果想要讓子類訪問(wèn),但是不想讓外界訪問(wèn),就可以使用protected受保護(hù)的訪問(wèn)控制。

(下面的內(nèi)容來(lái)自C++筆記3:C++核心編程中的4.6.2 繼承方式

總結(jié):
1.父類中的私有內(nèi)容(private)任何一種繼承方式都訪問(wèn)不到,即無(wú)法被訪問(wèn)/被繼承
2.公共繼承:父類中的各訪問(wèn)權(quán)限不變
3.保護(hù)繼承:父類中的各訪問(wèn)權(quán)限都變成protected保護(hù)權(quán)限
4.私有繼承:父類中的各訪問(wèn)權(quán)限都變成private私有權(quán)限

無(wú)繼承關(guān)系:

父類中的三個(gè)成員變量父類類內(nèi)訪問(wèn)類外通過(guò)父類對(duì)象訪問(wèn)
public修飾的num1可以訪問(wèn)可以訪問(wèn)
protected修飾的num2可以訪問(wèn)不能訪問(wèn)
private修飾的num3可以訪問(wèn)不能訪問(wèn)

子類公共繼承父類:class Zi : public Fu{ ... };

父類中的三個(gè)成員變量子類中的三個(gè)成員變量父類類內(nèi)訪問(wèn)子類類內(nèi)訪問(wèn)類外通過(guò)父類對(duì)象訪問(wèn)類外通過(guò)子類對(duì)象訪問(wèn)
public修飾的num1public修飾的num1可以訪問(wèn)可以訪問(wèn)可以訪問(wèn)可以訪問(wèn)
protected修飾的num2protected修飾的num2可以訪問(wèn)(因?yàn)橛欣^承關(guān)系,所以)
可以訪問(wèn)
不能訪問(wèn)不能訪問(wèn)
private修飾的num3private修飾的num3可以訪問(wèn)不能訪問(wèn)不能訪問(wèn)不能訪問(wèn)

子類保護(hù)繼承父類:class Zi : protected Fu{ ... };

父類中的三個(gè)成員變量子類中的三個(gè)成員變量父類類內(nèi)訪問(wèn)子類類內(nèi)訪問(wèn)類外通過(guò)父類對(duì)象訪問(wèn)類外通過(guò)子類對(duì)象訪問(wèn)
public修飾的num1protected修飾的num1可以訪問(wèn)可以訪問(wèn)可以訪問(wèn)不能訪問(wèn)
protected修飾的num2protected修飾的num2可以訪問(wèn)(因?yàn)橛欣^承關(guān)系,所以)
可以訪問(wèn)
不能訪問(wèn)不能訪問(wèn)
private修飾的num3private修飾的num3可以訪問(wèn)不能訪問(wèn)不能訪問(wèn)不能訪問(wèn)

子類私有繼承父類:class Zi : private Fu{ ... };

父類中的三個(gè)成員變量子類中的三個(gè)成員變量父類類內(nèi)訪問(wèn)子類類內(nèi)訪問(wèn)類外通過(guò)父類對(duì)象訪問(wèn)類外通過(guò)子類對(duì)象訪問(wèn)
public修飾的num1private修飾的num1可以訪問(wèn)可以訪問(wèn)可以訪問(wèn)不能訪問(wèn)
protected修飾的num2private修飾的num2可以訪問(wèn)(因?yàn)橛欣^承關(guān)系,所以)
可以訪問(wèn)
不能訪問(wèn)不能訪問(wèn)
private修飾的num3private修飾的num3可以訪問(wèn)不能訪問(wèn)不能訪問(wèn)不能訪問(wèn)

示例:

#include<iostream> using namespace std;class Fu{ public:int num1; protected:int num2; private:int num3;public:void func(){num1 = 10;num2 = 20;num3 = 30;} }; class Zi : protected Fu{ //protected保護(hù)繼承 public公共繼承 private私有繼承 public:void func1(){num1 = 10;num2 = 20;num3 = 30;} };int main(){Fu fu;cout << fu.num1 << endl;cout << fu.num2 << endl;cout << fu.num3 << endl;Zi zi;cout << zi.num1 << endl;cout << zi.num2 << endl;cout << zi.num3 << endl; }

繼承中的對(duì)象模型(成員變量和成員函數(shù)分開(kāi)存儲(chǔ))

類中的成員變量和成員函數(shù)是分開(kāi)存儲(chǔ)的。
在對(duì)象中,只保存了(非靜態(tài))成員變量的信息;
子類將父類中的所有成員都繼承了過(guò)來(lái),包括私有的成員(變量和方法)。

(筆記①:牛客校招沖刺集訓(xùn)營(yíng)—C++工程師中的5.3.8 靜態(tài)成員(靜態(tài)成員變量和靜態(tài)成員函數(shù))補(bǔ)充:成員變量和成員函數(shù)分開(kāi)存儲(chǔ) 中也有講到)

普通成員變量(非靜態(tài)成員變量)屬于類的對(duì)象
普通成員函數(shù)(非靜態(tài)成員函數(shù))、靜態(tài)成員變量、靜態(tài)成員函數(shù)屬于類本身

空對(duì)象占1個(gè)字節(jié)。

示例:

#include<iostream> using namespace std;class Fu{ public:int num1;//4個(gè)字節(jié) 非靜態(tài)成員變量 protected:int* num2;//8個(gè)字節(jié) 非靜態(tài)成員變量 private:long num3;//8個(gè)字節(jié) 非靜態(tài)成員變量 public:static int num4;//靜態(tài)成員變量void func(){}//非靜態(tài)成員函數(shù)static void func1(){}//靜態(tài)成員函數(shù) }; class Zi : public Fu{ public:int num5;//4個(gè)字節(jié) 非靜態(tài)成員變量 protected: int* num6;//8個(gè)字節(jié) 非靜態(tài)成員變量 private: long num7;//8個(gè)字節(jié) 非靜態(tài)成員變量 public:static int num8; //靜態(tài)成員變量void func2(){}//非靜態(tài)成員函數(shù)static void func3(){} //靜態(tài)成員函數(shù) };int main(){Fu fu;cout << "一個(gè)具體的對(duì)象的大小:" << sizeof(fu) << endl;//24cout << "一個(gè)類的大小:" << sizeof(Fu) << endl;//48Zi zi;cout << "一個(gè)具體的對(duì)象的大小:" << sizeof(zi) << endl;cout << "一個(gè)類的大小:" << sizeof(Zi) << endl;return 0; }

結(jié)果:
(為什么是24不是20,因?yàn)?strong>字節(jié)對(duì)齊(內(nèi)存對(duì)齊))

一個(gè)具體的對(duì)象的大小:24 一個(gè)類的大小:24 一個(gè)具體的對(duì)象的大小:48 一個(gè)類的大小:48

如果把父類中的內(nèi)容都屏蔽掉,結(jié)果如下:(空對(duì)象占1個(gè)字節(jié))

class Fu{ public://int num1;//4個(gè)字節(jié) 非靜態(tài)成員變量//int* num2;//8個(gè)字節(jié) 非靜態(tài)成員變量//long num3;//8個(gè)字節(jié) 非靜態(tài)成員變量//static int num4; //靜態(tài)成員變量//void func(){}//非靜態(tài)成員函數(shù)//static void func1(){} //靜態(tài)成員函數(shù) };結(jié)果: 一個(gè)具體的對(duì)象的大小:1 一個(gè)類的大小:1 一個(gè)具體的對(duì)象的大小:24 一個(gè)類的大小:24

如果只屏蔽父類中的非靜態(tài)成員變量,結(jié)果如下:(空對(duì)象占1個(gè)字節(jié))

class Fu{ public://int num1;//4個(gè)字節(jié) 非靜態(tài)成員變量//int* num2;//8個(gè)字節(jié) 非靜態(tài)成員變量//long num3;//8個(gè)字節(jié) 非靜態(tài)成員變量static int num4; //靜態(tài)成員變量void func(){}//非靜態(tài)成員函數(shù)static void func1(){} //靜態(tài)成員函數(shù) };結(jié)果: 一個(gè)具體的對(duì)象的大小:1 一個(gè)類的大小:1 一個(gè)具體的對(duì)象的大小:24 一個(gè)類的大小:24

所以說(shuō):
普通成員變量(非靜態(tài)成員變量)屬于類的對(duì)象
普通成員函數(shù)(非靜態(tài)成員函數(shù))、靜態(tài)成員變量、靜態(tài)成員函數(shù)屬于類本身

(這里第一次用到了對(duì)象模型來(lái)輔助理解)
具體是通過(guò)Visual Studio的工具查看一個(gè)類的內(nèi)存分布:
1.打開(kāi)這個(gè)工具;
2.切換到當(dāng)前原文件的目錄;
3.cl /d1 reportSingleClassLayout類名 文件名

繼承中的構(gòu)造和析構(gòu)順序

(見(jiàn)筆記①:牛客校招沖刺集訓(xùn)營(yíng)—C++工程師中的5.3.7 類對(duì)象作為類成員(構(gòu)造和析構(gòu)的順序)
(見(jiàn)C++筆記3:C++核心編程中的4.6.4 繼承中的構(gòu)造和析構(gòu)順序
繼承中 先調(diào)用父類構(gòu)造函數(shù),再調(diào)用子類構(gòu)造函數(shù),析構(gòu)順序與構(gòu)造相反。

視頻課中的筆記:

訪問(wèn)繼承中的 非靜態(tài) 同名 成員

出現(xiàn)同名成員,就會(huì)出現(xiàn)二義性的現(xiàn)象,一般是通過(guò)加作用域的方式來(lái)避免出現(xiàn)二義性。

(見(jiàn)C++筆記3:C++核心編程中的4.6.5 繼承同名成員處理方式

問(wèn)題:當(dāng)子類與父類出現(xiàn)同名的成員,如何通過(guò)子類對(duì)象,訪問(wèn)到子類或父類中同名的數(shù)據(jù)呢
答:
子類對(duì)象可以直接訪問(wèn)到子類中同名成員;
子類對(duì)象加作用域可以訪問(wèn)到父類同名成員;
當(dāng)子類與父類擁有同名的成員函數(shù),子類會(huì)隱藏父類中所有同名成員函數(shù),加作用域可以訪問(wèn)到父類中同名函數(shù)。

//子類與父類出現(xiàn)相同的成員(變量/函數(shù))時(shí),子類對(duì)象如何訪問(wèn)到同名的數(shù)據(jù)?Son1 son;//同名成員變量cout << "子類中的a = " << son.a << endl;//直接訪問(wèn)cout << "父類中的a = " << son.Base1::a << endl;//加父類的作用域//同名成員函數(shù)son.func();//直接訪問(wèn)son.Base1::func();//加父類的作用域son.Base1::func(10);//加父類的作用域

視頻課里的例子:(視頻課從19:28開(kāi)始)

訪問(wèn)繼承中的 靜態(tài) 同名 成員

當(dāng)子類與父類出現(xiàn)同名的成員,如何通過(guò)子類對(duì)象,訪問(wèn)到子類或父類中同名的數(shù)據(jù)呢
對(duì)于同名的靜態(tài)成員,也是加上作用域

但是,由于靜態(tài)成員(變量和函數(shù))被所有對(duì)象共享,所以一般不通過(guò)子類對(duì)象來(lái)訪問(wèn)這些同名成員,而是直接加上父類類名的作用域來(lái)訪問(wèn)

總結(jié):如何訪問(wèn)繼承中的同名成員(靜態(tài)成員和非靜態(tài)成員)

訪問(wèn)繼承中的同名成員有一下幾種方式:

  • 通過(guò)父類對(duì)象訪問(wèn)父類中的非靜態(tài)成員和靜態(tài)成員;
  • 通過(guò)子類對(duì)象訪問(wèn)子類中的非靜態(tài)成員和靜態(tài)成員;
  • 通過(guò)子類對(duì)象訪問(wèn)父類中的非靜態(tài)成員和靜態(tài)成員;
  • 不通過(guò)對(duì)象來(lái)訪問(wèn),直接加個(gè)作用域行不行?
    答:靜態(tài)成員可以直接加個(gè)作用域來(lái)訪問(wèn),非靜態(tài)成員必須通過(guò)特定的對(duì)象來(lái)訪問(wèn)
    方式4的理由:
    由于靜態(tài)成員(變量和函數(shù))被所有對(duì)象共享,所以一般不通過(guò)子類對(duì)象來(lái)訪問(wèn)這些同名成員,而是直接加上父類類名的作用域來(lái)訪問(wèn)
    非靜態(tài)成員就必須要通過(guò)具體的對(duì)象來(lái)訪問(wèn)了。
  • 代碼:

    #include<iostream> using namespace std;class Fu{ public:int num1;//非靜態(tài)成員變量static int num4;//靜態(tài)成員變量void func(){}//非靜態(tài)成員函數(shù)static void func1(){}//靜態(tài)成員函數(shù) }; class Zi : public Fu{ public:int num1;//非靜態(tài)成員變量static int num4;//靜態(tài)成員變量void func(){}//非靜態(tài)成員函數(shù)static void func1(){}//靜態(tài)成員函數(shù) };int main(){//通過(guò)父類對(duì)象訪問(wèn)父類中的非靜態(tài)成員和靜態(tài)成員:Fu fu;cout << fu.num1 << endl;cout << fu.num4 << endl;fu.func();fu.func1();//通過(guò)子類對(duì)象訪問(wèn)子類中的非靜態(tài)成員和靜態(tài)成員:Zi zi;cout << zi.num1 << zi.num4 << endl;zi.func();zi.func1();//通過(guò)子類對(duì)象訪問(wèn)父類中的非靜態(tài)成員和靜態(tài)成員:cout << zi.Fu::num1 << endl;cout << zi.Fu::num4 << endl;zi.Fu::func();zi.Fu::func1();//不通過(guò)對(duì)象來(lái)訪問(wèn),直接加個(gè)作用域行不行? 靜態(tài)成員可以直接加個(gè)作用域來(lái)訪問(wèn),非靜態(tài)成員必須通過(guò)特定的對(duì)象來(lái)訪問(wèn)cout << Fu::num1 << endl;//非靜態(tài)成員引用必須與特定對(duì)象相對(duì)cout << Fu::num4 << endl;Fu::func();//非靜態(tài)成員引用必須與特定對(duì)象相對(duì)Fu::func1();cout << Zi::num1 << endl;//非靜態(tài)成員引用必須與特定對(duì)象相對(duì)cout << Zi::num4 << endl;Zi::func();//非靜態(tài)成員引用必須與特定對(duì)象相對(duì)Zi::func1();return 0; }

    多繼承/多重繼承

    多繼承
    概念:一個(gè)類繼承多個(gè)類
    語(yǔ)法:class 子類: 繼承方式 父類1, 繼承方式 父類2...
    注意:繼承方式不要省略,否則就默認(rèn)是私有繼承

    C++實(shí)際開(kāi)發(fā)中不建議用多繼承,從多個(gè)類繼承可能導(dǎo)致成員方法或成員變量同名產(chǎn)生較多的歧義


    看個(gè)示例:
    基類Base1:

    基類Base2:

    子類多繼承Base1和Base2:

    main函數(shù):

    輸出m_A的時(shí)候兩個(gè)父類都有,就沒(méi)辦法直接訪問(wèn)了,要加上作用域;
    輸出m_B的時(shí)候就可以直接輸出,或者也可以加上作用域。

    菱形繼承–>虛繼承、虛基類☆☆☆

    什么是菱形繼承?
    菱形繼承會(huì)帶來(lái)什么問(wèn)題?
    怎么解決?


    示例:
    Person類:

    Singer類和Waiter類都繼承自Person類,然后SingerWaiter類多繼承Singer類和Waiter類:

    main函數(shù):

    解決方法:給Singer類和Waiter類的繼承方式后面加上virtual關(guān)鍵字,就成了虛繼承,此時(shí)Person類被稱為虛基類

    結(jié)果:

    虛繼承的實(shí)現(xiàn)原理

    vbptr:virtual base pointer(虛基類指針)
    原理:
    只有一個(gè)唯一的成員,通過(guò)保存虛基類指針,這個(gè)指針指向一張表(虛基類表),這個(gè)表中保存了當(dāng)前獲取到唯一的數(shù)據(jù)的偏移量offset。


    (第二次用了對(duì)象模型來(lái)輔助理解)

    5.3.35-38 多態(tài)(一般是指動(dòng)態(tài)多態(tài))

    靜態(tài)聯(lián)編和動(dòng)態(tài)聯(lián)編(靜態(tài)多態(tài)和動(dòng)態(tài)多態(tài))

    以下的內(nèi)容來(lái)自c++筆記3的4.7.1 多態(tài)的基本概念

    ①多態(tài)分為兩類:

    • 靜態(tài)多態(tài): 函數(shù)重載運(yùn)算符重載 屬于靜態(tài)多態(tài),復(fù)用函數(shù)名;
    • 動(dòng)態(tài)多態(tài): 派生類和虛函數(shù)實(shí)現(xiàn)運(yùn)行時(shí)多態(tài),一般我們說(shuō)多態(tài)指的都是動(dòng)態(tài)多態(tài)

    ②靜態(tài)多態(tài)和動(dòng)態(tài)多態(tài)區(qū)別:

    • 靜態(tài)多態(tài)的函數(shù)地址早綁定 - 編譯階段確定函數(shù)地址
    • 動(dòng)態(tài)多態(tài)的函數(shù)地址晚綁定 - 運(yùn)行階段確定函數(shù)地址

    ③動(dòng)態(tài)多態(tài)滿足條件:

    • 繼承關(guān)系
    • 子類重寫(xiě)父類中的虛函數(shù)(virtual + 函數(shù)名)

    ④動(dòng)態(tài)多態(tài)使用條件

    • 父類指針或引用指向子類對(duì)象

    ⑤重寫(xiě)和重載的區(qū)別
    重寫(xiě):

    • 函數(shù)返回值類型、函數(shù)名、參數(shù)列表完全一致稱為重寫(xiě)
    • 重寫(xiě)也叫覆蓋、覆寫(xiě)。

    重載:
    ①同一個(gè)作用域下;
    ②函數(shù)名稱相同;
    ③函數(shù)參數(shù)的 類型不同、個(gè)數(shù)不同 、順序不同;
    ④和返回值類型、函數(shù)形參名無(wú)關(guān);

    示例:
    關(guān)鍵在于父類中成員函數(shù)前的virtual關(guān)鍵字

    #include<iostream> using namespace std;//動(dòng)物類 class Animals { public://函數(shù)前面加上virtual關(guān)鍵字,speak函數(shù)就是虛函數(shù)virtual void speak() {cout << "動(dòng)物在說(shuō)話" << endl;} }; //貓類 class Cats: public Animals{ public:void speak() {cout << "小貓?jiān)谡f(shuō)話" << endl;} }; class Dogs:public Animals { public:void speak() {cout << "小狗在說(shuō)話" << endl;} }; //全局函數(shù):父類引用指向子類對(duì)象 // void doSpeak(Animals& ani) { // ani.speak(); // } //全局函數(shù):父類指針指向子類對(duì)象 void doSpeak(Animals* ani) {//ani->speak();(*ani).speak(); }int main(){cout << "sizeof Animals類 = " << sizeof(Animals) << endl;//有virtual關(guān)鍵字的Animals類占4字節(jié)//沒(méi)有virtual關(guān)鍵字的Animals類占1字節(jié),空類,并且非靜態(tài)成員函數(shù)不屬于類的內(nèi)存(見(jiàn)4.3.1 成員變量和成員函數(shù)分開(kāi)存儲(chǔ))//加了virtual關(guān)鍵字后Animals類占4字節(jié),不再是空類,而是多了一個(gè)指針,叫vfptr(虛函數(shù)表指針),表內(nèi)記錄虛函數(shù)的地址Cats cat;//當(dāng)子類 重寫(xiě) 父類的 虛函數(shù) ,子類中的虛函數(shù)表內(nèi)部會(huì)替換成子類的虛函數(shù)地址//子類重寫(xiě)父類的虛函數(shù),即子類也有個(gè)vfptr(虛函數(shù)表指針),表內(nèi)記錄虛函數(shù)的地址cout << "sizeof Cats類 = " << sizeof(Cats) << endl;//4 //當(dāng)父類的 指針或者引用 指向子類對(duì)象的時(shí)候,就發(fā)生了多態(tài)//doSpeak(cat);//小貓?jiān)谡f(shuō)話 父類引用指向子類對(duì)象doSpeak(&cat);//小貓?jiān)谡f(shuō)話 父類指針指向子類對(duì)象Dogs dog;//doSpeak(dog);//小狗在說(shuō)話 父類引用指向子類對(duì)象doSpeak(&dog);//小狗在說(shuō)話 父類指針指向子類對(duì)象system("pause");return 0; }

    父類的speak函數(shù)前不加關(guān)鍵字virtual,結(jié)果如下:(靜態(tài)多態(tài))

    sizeof Animals類 = 1 //空類(非靜態(tài)成員函數(shù)不屬于對(duì)象的內(nèi)存) sizeof Cats類 = 1 動(dòng)物在說(shuō)話 動(dòng)物在說(shuō)話

    結(jié)果是調(diào)用了父類的speak函數(shù),這屬于地址早綁定,也叫靜態(tài)聯(lián)編,因?yàn)樵诰幾g期間就知道父類speak函數(shù)的地址了。
    而我們想要的結(jié)果是如果傳進(jìn)來(lái)是貓類的對(duì)象,就執(zhí)行貓的speak函數(shù);傳進(jìn)來(lái)是狗類的對(duì)象,就執(zhí)行狗的speak函數(shù);這屬于地址晚綁定,也叫動(dòng)態(tài)聯(lián)編。具體做法就是

    在父類的speak函數(shù)前加關(guān)鍵字virtual,結(jié)果如下:(動(dòng)態(tài)多態(tài))

    sizeof Animals類 = 8 //虛函數(shù)表指針vfptr的大小 sizeof Cats類 = 8 小貓?jiān)谡f(shuō)話 小狗在說(shuō)話

    虛函數(shù)的原理(多態(tài)的底層原理)

    main函數(shù)中的部分代碼:

    cout << "sizeof Animals類 = " << sizeof(Animals) << endl;//有virtual關(guān)鍵字的Animals類占4字節(jié)//沒(méi)有virtual關(guān)鍵字的Animals類占1字節(jié),空類,并且非靜態(tài)成員函數(shù)不屬于類的內(nèi)存(見(jiàn)4.3.1 成員變量和成員函數(shù)分開(kāi)存儲(chǔ))//加了virtual關(guān)鍵字后Animals類占4字節(jié),不再是空類,而是多了一個(gè)指針,叫vfptr(虛函數(shù)表指針),表內(nèi)記錄虛函數(shù)的地址Cats cat;//當(dāng)子類 重寫(xiě) 父類的 虛函數(shù) ,子類中的虛函數(shù)表內(nèi)部會(huì)替換成子類的虛函數(shù)地址//子類重寫(xiě)父類的虛函數(shù),即子類也有個(gè)vfptr(虛函數(shù)表指針),表內(nèi)記錄虛函數(shù)的地址cout << "sizeof Cats類 = " << sizeof(Cats) << endl;//4

    解釋:
    ①?zèng)]有virtual關(guān)鍵字的Animals類占1字節(jié),空類,因?yàn)榉庆o態(tài)成員函數(shù)不屬于對(duì)象的內(nèi)存(見(jiàn)繼承中的對(duì)象模型(成員變量和成員函數(shù)分開(kāi)存儲(chǔ)));
    ②加了virtual關(guān)鍵字后Animals類占4字節(jié)(32位操作系統(tǒng))/8個(gè)字節(jié)(64位操作系統(tǒng)),不再是空類,而是多了一個(gè)指針,叫vfptr(虛函數(shù)表指針),表內(nèi)記錄虛函數(shù)的地址;虛函數(shù)表指針指向虛函數(shù)表vftable;
    ③由于子類重寫(xiě)父類的虛函數(shù),因此子類也有個(gè)vfptr(虛函數(shù)表指針),表內(nèi)記錄虛函數(shù)的地址;
    ④在子類重寫(xiě)父類的虛函數(shù)時(shí),子類中的虛函數(shù)表內(nèi)部會(huì)替換成子類的虛函數(shù)地址

    多態(tài)的底層原理:

    • 首先在父類中的虛函數(shù)(virtual void Speak(){}),使得父類占4個(gè)字節(jié)(32位操作系統(tǒng))/8個(gè)字節(jié)(64位操作系統(tǒng)),這4個(gè)字節(jié)是個(gè)vfptr(虛函數(shù)表指針),它指向虛函數(shù)表(vftable),表內(nèi)記錄虛函數(shù)的地址(&Animal::speak);
    • 然后是子類重寫(xiě)父類中的虛函數(shù),因此子類也占4個(gè)字節(jié),這4個(gè)字節(jié)也是個(gè)vfptr(虛函數(shù)表指針),它也指向虛函數(shù)表(vftable),表內(nèi)也記錄虛函數(shù)的地址;在子類重寫(xiě)父類中的虛函數(shù)后,子類中的虛函數(shù)表內(nèi)部會(huì)替換成子類的虛函數(shù)地址(&Cats::speak)。
    • 最后是當(dāng)父類的指針或者引用指向子類對(duì)象時(shí),就發(fā)生了多態(tài)

    派生類虛表:
    1.先將基類的虛表中的內(nèi)容拷貝一份;
    2.如果派生類對(duì)基類中的虛函數(shù)進(jìn)行重寫(xiě),使用派生類的虛函數(shù)替換相同偏移量位置的基類虛函數(shù);
    3.如果派生類中新增加自己的虛函數(shù),按照其在派生類中的聲明次序,放在上述虛函數(shù)之后。
    原文鏈接:https://blog.csdn.net/qq_39412582/article/details/81628254

    (視頻課中從01:22:00開(kāi)始)

    靜態(tài)多態(tài):

    動(dòng)態(tài)多態(tài):

    (第三次用了對(duì)象模型來(lái)輔助理解)
    ①父類中的speak函數(shù)前沒(méi)加virtual,查看Animal類的內(nèi)存分布:

    ②父類中的speak函數(shù)前加了virtual:
    查看Animal類的內(nèi)存分布:

    然后再查看Cats類的內(nèi)存分布:


    再查看Dog類的內(nèi)存分布:

    如果Cats類不重寫(xiě)父類的speak函數(shù),它的內(nèi)存分布就變成了:

    多態(tài)案例(開(kāi)閉原則:對(duì)擴(kuò)展進(jìn)行開(kāi)放,對(duì)修改進(jìn)行關(guān)閉)

    視頻課中的案例和c++筆記3的4.7.2 多態(tài)案例1—計(jì)算器類中的案例一樣。

    如果想擴(kuò)展新的功能,需要修改源碼。
    在真實(shí)開(kāi)發(fā)中提倡開(kāi)閉原則
    開(kāi)閉原則:對(duì)擴(kuò)展進(jìn)行開(kāi)放,對(duì)修改進(jìn)行關(guān)閉。

    多態(tài)技術(shù):
    ①繼承②父類有虛函數(shù)③子類重寫(xiě)父類的虛函數(shù)④父類的指針或引用指向子類對(duì)象

    重寫(xiě):函數(shù)返回值類型 函數(shù)名 參數(shù)列表 完全一致稱為重寫(xiě)

    純虛函數(shù) --> 抽象類

    在多態(tài)中,通常父類中虛函數(shù)的現(xiàn)實(shí)無(wú)意義的,主要都是調(diào)用子類重寫(xiě)的內(nèi)容,所以可以將虛函數(shù)改為“純虛函數(shù)”。

    純虛函數(shù)語(yǔ)法:virtual 返回值類型 函數(shù)名 (形參列表) = 0;

    父類中有了純虛函數(shù),這個(gè)類就被稱為抽象類

    抽象類特點(diǎn):

    • 無(wú)法實(shí)例化對(duì)象;
    • ②子類必須重寫(xiě)抽象類中的純虛函數(shù)
      如果子類沒(méi)有重寫(xiě)父類的純虛函數(shù),那么子類也是一個(gè)抽象類。

    示例:

    //父類:抽象計(jì)算器 class abstractCalculator { public:int a = 0, b = 0;//virtual int getResult() {//②虛函數(shù)// return 0;//}virtual int getResult() = 0;//純虛函數(shù) };

    虛析構(gòu)和純虛析構(gòu)(解決 調(diào)用不到子類析構(gòu)函數(shù) 的問(wèn)題)

    多態(tài)使用時(shí),如果子類中有屬性開(kāi)辟到堆區(qū),那么父類指針在釋放時(shí)無(wú)法調(diào)用到子類的析構(gòu)代碼

    解決方式:將父類中的析構(gòu)函數(shù)改為虛析構(gòu)或者純虛析構(gòu)(☆☆☆推薦用虛析構(gòu))。

    總結(jié):

  • 虛析構(gòu)或純虛析構(gòu)就是用來(lái)解決通過(guò)父類指針釋放子類對(duì)象;
  • 如果子類中沒(méi)有堆區(qū)數(shù)據(jù),可以不寫(xiě)為虛析構(gòu)或純虛析構(gòu);
  • 擁有純虛析構(gòu)函數(shù)的類也屬于抽象類,
    純虛析構(gòu)的目的只有一個(gè):讓類成為抽象類
  • 純虛析構(gòu)需要有聲明,也要有實(shí)現(xiàn)
    (在類內(nèi)聲明)virtual ~Animal() = 0;
    (在類外實(shí)現(xiàn))Animal::~Animal(){}

    注意:
    純虛函數(shù)不用實(shí)現(xiàn),但子類必須重寫(xiě)純虛函數(shù),否則子類也是抽象類;
    純虛析構(gòu)必須要實(shí)現(xiàn),而且只能在類外實(shí)現(xiàn)

    class Animal{ public:Animal(){cout << "Animal類的構(gòu)造" << endl;}virtual void speak() = 0;//純虛函數(shù) 子類必須重寫(xiě)純虛函數(shù)//純虛析構(gòu):要聲明,也要實(shí)現(xiàn)virtual ~Animal() = 0;//在類內(nèi)聲明 };//純虛析構(gòu):在類外實(shí)現(xiàn) Animal::~Animal(){cout << "Animal類的析構(gòu)" << endl; }

    示例:

    #include<iostream> #include<string.h> using namespace std;class Animal{ public:Animal(){cout << "Animal類的構(gòu)造" << endl;}virtual void speak() = 0;//純虛函數(shù)//常規(guī)的析構(gòu)函數(shù): 會(huì)帶來(lái) 無(wú)法調(diào)用子類析構(gòu)函數(shù) 的問(wèn)題~Animal(){cout << "Animal類的析構(gòu)" << endl; }//虛析構(gòu): // virtual ~Animal(){ // cout << "Animal類的析構(gòu)" << endl; // }//純虛析構(gòu):要聲明,也要實(shí)現(xiàn) // virtual ~Animal() = 0;//在類內(nèi)聲明 };//純虛析構(gòu):在類外實(shí)現(xiàn) // Animal::~Animal(){ // cout << "Animal類的析構(gòu)" << endl; // }class Cats : public Animal{ public: Cats(const char* name){cout << "Cats類的有參構(gòu)造" << endl;this->m_Name = new char(strlen(name) + 1);strcpy(this->m_Name, name);}void speak(){cout << this->m_Name << "小貓?jiān)谡f(shuō)話..." << endl;}~Cats(){cout << "Cats類的析構(gòu)" << endl; if(this->m_Name != nullptr){delete[] this->m_Name;this->m_Name = nullptr;}} private:char* m_Name; };int main(){Animal* ani = new Cats("Tom");ani->speak();delete ani;return 0; }

    結(jié)果:

    Animal類的構(gòu)造 Cats類的有參構(gòu)造 Tom小貓?jiān)谡f(shuō)話... Animal類的析構(gòu)

    沒(méi)有調(diào)用子類的析構(gòu)函數(shù),解決辦法是在父類的析構(gòu)函數(shù)前面加個(gè)virtual,將其變?yōu)樘撐鰳?gòu)

    class Animal{ public:Animal(){cout << "Animal類的構(gòu)造" << endl;}virtual void speak() = 0;//純虛函數(shù)//虛析構(gòu):virtual ~Animal(){cout << "Animal類的析構(gòu)" << endl; } };

    然后再編譯運(yùn)行:

    Animal類的構(gòu)造 Cats類的有參構(gòu)造 Tom小貓?jiān)谡f(shuō)話... Cats類的析構(gòu) Animal類的析構(gòu)

    或者寫(xiě)成純虛析構(gòu)的形式:

    class Animal{ public:Animal(){cout << "Animal類的構(gòu)造" << endl;}virtual void speak() = 0;//純虛函數(shù)//純虛析構(gòu):要聲明,也要實(shí)現(xiàn)virtual ~Animal() = 0;//在類內(nèi)聲明 };//純虛析構(gòu):在類外實(shí)現(xiàn) Animal::~Animal(){cout << "Animal類的析構(gòu)" << endl; }

    那么當(dāng)子類中有屬性開(kāi)辟到堆區(qū),為什么會(huì)出現(xiàn)無(wú)法調(diào)用到子類的析構(gòu)代碼的問(wèn)題呢?
    可以聯(lián)想到上面的靜態(tài)聯(lián)編和動(dòng)態(tài)聯(lián)編中說(shuō)的:

    父類的speak函數(shù)前如果不加關(guān)鍵字virtual,最終的結(jié)果就是調(diào)用了父類的speak函數(shù)(即輸出"動(dòng)物在說(shuō)話"),這里也一樣,父類的析構(gòu)函數(shù)前沒(méi)有關(guān)鍵字virtual,最終的結(jié)果就是調(diào)用了父類的析構(gòu)函數(shù),所以就沒(méi)有調(diào)用子類的析構(gòu)函數(shù)

    那么怎么解決呢?
    方法和上圖中的內(nèi)容類似,就是在父類的析構(gòu)函數(shù)前加上關(guān)鍵字virtual,這樣的話就可以調(diào)用到子類的析構(gòu)函數(shù)了。具體解釋見(jiàn)下圖:
    (視頻課中從01:56:40開(kāi)始)
    (第四次用了對(duì)象模型)
    Animal類的析構(gòu)函數(shù)前加了關(guān)鍵字virtual,查看Cat類的內(nèi)存分布:

    Cat類的析構(gòu)函數(shù)就會(huì)加入到虛函數(shù)表中,這樣就可以調(diào)用到了:

    析構(gòu)函數(shù):destructor
    構(gòu)造函數(shù):constructor

    C++面試寶典–>第一章–>1.3 面向?qū)ο?/h3>

    E:\找工作\C++八股文\C面試寶典完整版最最最新.pdf
    視頻課中從02:00:39開(kāi)始

    5.6 內(nèi)存管理①(結(jié)合計(jì)算機(jī)操作系統(tǒng)筆記)

    (這部分內(nèi)容可以看計(jì)算機(jī)操作系統(tǒng)筆記 的0620開(kāi)始一直到第三章結(jié)束)

    程序就是文件;
    運(yùn)行起來(lái)的程序被稱為進(jìn)程

    01:00:35開(kāi)始回顧第一節(jié)課的內(nèi)容:

    1.重定位(地址轉(zhuǎn)換:邏輯地址–>物理地址)

    重定位:修改該程序中的地址(相對(duì)地址)

    什么時(shí)候完成重定位?編譯時(shí)?還是載入時(shí)?
    都不對(duì):
    編譯時(shí)重定位的程序只能放在內(nèi)存固定位置;
    載入時(shí)重定位的程序一旦載入內(nèi)存就不能動(dòng)了;
    答案是在運(yùn)行時(shí)(執(zhí)行每條指令時(shí)才)完成重定位,找到真正的物理地址。
    (分別對(duì)應(yīng)操作系統(tǒng)筆記中的絕對(duì)裝入(載入)、靜態(tài)重定位、動(dòng)態(tài)重定位

    也可以叫地址翻譯:基地址(起始地址) + 邏輯地址(偏移量)–> 物理地址

    2.交換技術(shù)

    (對(duì)應(yīng)操作系統(tǒng)筆記中的內(nèi)存空間的擴(kuò)充:交換技術(shù),是指內(nèi)存和外存之間交換進(jìn)程,以緩解內(nèi)存吃緊的問(wèn)題)

    交換技術(shù):
    (要運(yùn)行進(jìn)程2,但內(nèi)存不夠了)

    (進(jìn)程1處于睡眠狀態(tài),就把進(jìn)程1換出到磁盤(pán)中,把進(jìn)程2換入到內(nèi)存中)

    (然后進(jìn)程3頁(yè)進(jìn)入睡眠狀態(tài),把進(jìn)程3換出磁盤(pán),把剛剛換出的進(jìn)程1再換入到內(nèi)存中)

    3.分段(將各段分別放入內(nèi)存)

    程序是分段管理的;
    程序運(yùn)行時(shí)是分段加載的,而不是將整個(gè)程序一次性全部載入內(nèi)存

    (對(duì)應(yīng)操作系統(tǒng)筆記中的分段存儲(chǔ)管理的邏輯地址結(jié)構(gòu):<段號(hào)/段名,段內(nèi)地址/段內(nèi)偏移量>

    分段:將各段程序分別放入內(nèi)存。
    (對(duì)應(yīng)操作系統(tǒng)比較中的段表中記錄的內(nèi)容:段號(hào)、段的起始地址、段的長(zhǎng)度

    具體怎么分段?
    有固定分區(qū)和可變分區(qū)(動(dòng)態(tài)分區(qū)):
    (對(duì)應(yīng)操作系統(tǒng)筆記中的連續(xù)分配中的固定分區(qū)分配和可變分區(qū)分配(動(dòng)態(tài)分區(qū)分配)

    可變分區(qū)算法:首先適配、最佳適配、最差適配。
    (對(duì)應(yīng)操作系統(tǒng)筆記中的動(dòng)態(tài)分區(qū)分配算法:首次適應(yīng)、最佳時(shí)應(yīng)、最壞適應(yīng)、臨近時(shí)應(yīng)

    內(nèi)存緊縮 & 內(nèi)存碎片
    (對(duì)應(yīng)操作系統(tǒng)筆記中的內(nèi)存緊縮技術(shù),用來(lái)解決外部碎片的問(wèn)題。

    4.分頁(yè)(從連續(xù)到離散)

    分頁(yè):頁(yè)表的內(nèi)容(頁(yè)號(hào)、內(nèi)存塊號(hào)/頁(yè)框號(hào)) 邏輯地址結(jié)構(gòu):<頁(yè)號(hào),頁(yè)內(nèi)地址偏移量>

    為了提高內(nèi)存空間利用率,頁(yè)的大小應(yīng)該足夠小,但頁(yè)表就大了,所以就有了二級(jí)頁(yè)表,即頁(yè)表的頁(yè)表,稱為頁(yè)目錄表

    二級(jí)頁(yè)表的邏輯地址結(jié)構(gòu):頁(yè)目錄號(hào)、頁(yè)號(hào)、頁(yè)內(nèi)偏移量

    二級(jí)頁(yè)表的出現(xiàn)是因?yàn)闆](méi)必要把所有的頁(yè)表項(xiàng)都放在內(nèi)存中,很占內(nèi)存,所以就弄成二級(jí)頁(yè)表,把用的頁(yè)表放到內(nèi)存中,沒(méi)用到的先放外存中,這樣就提高了內(nèi)存的利用率。

    通過(guò)二級(jí)頁(yè)表訪問(wèn)一個(gè)邏輯地址需要三次訪存
    第一次訪問(wèn)內(nèi)存中的頁(yè)目錄表,第二次訪問(wèn)內(nèi)存中的頁(yè)表,第三次訪問(wèn)目標(biāo)內(nèi)存單元。

    因?yàn)樾枰卧L存,所以引入快表,可以讓訪存次數(shù)降低一次。快表的查詢速度非常快。

    5.7 內(nèi)存管理②(結(jié)合計(jì)算機(jī)操作系統(tǒng)筆記)

    5.段頁(yè)式管理 和 虛擬內(nèi)存(虛擬地址空間/虛擬內(nèi)存地址)

    (視頻課中從32:52開(kāi)始)

    這里面的段就是虛擬內(nèi)存,那虛擬內(nèi)存中具體是怎么分段的,都分為哪些分區(qū)?就是下面的虛擬地址空間,或者叫虛擬內(nèi)存地址。

    C++筆記3:C++核心編程 --> 1、內(nèi)存分區(qū)模型
    C++ Primer Plus(嵌入式公開(kāi)課)—第4章 復(fù)合類型–>4.8.5 自動(dòng)存儲(chǔ)、靜態(tài)存儲(chǔ)和動(dòng)態(tài)存儲(chǔ)

    C++的內(nèi)存分區(qū)/內(nèi)存模型:(下圖的虛擬內(nèi)存地址中的用戶區(qū)
    全局區(qū)(靜態(tài)存儲(chǔ))、棧區(qū)(自動(dòng)存儲(chǔ))、堆區(qū)/自由存儲(chǔ)區(qū)(動(dòng)態(tài)存儲(chǔ))

    每個(gè)進(jìn)程都有一個(gè)虛擬地址空間;
    同一個(gè)進(jìn)程下的不同線程共用一個(gè)虛擬地址空間。


    共享庫(kù):靜態(tài)庫(kù)、共享內(nèi)存;
    棧:局部變量、返回值(自動(dòng)釋放)后進(jìn)先出
    堆區(qū):malloc或者new的數(shù)據(jù),要手動(dòng)釋放
    全局區(qū):.bss(未初始化或初始化為0的全局變量)、.data(已初始化全局變量)、.text(代碼段、二進(jìn)制機(jī)器指令)

    內(nèi)存分區(qū)權(quán)限
    共享庫(kù)靜態(tài)庫(kù)、共享內(nèi)存
    棧區(qū)局部變量、返回值(自動(dòng)釋放)后進(jìn)先出可讀可寫(xiě)
    堆區(qū)malloc或者new的數(shù)據(jù)要手動(dòng)釋放free或者delete可讀可寫(xiě)
    全局區(qū):
    .bss未初始化或初始化為0的全局變量
    .data已初始化的全局變量
    .text代碼段只讀
    常量(全局常量+字符串常量)只讀
    靜態(tài)變量(static)

    缺頁(yè)中斷

    6.虛擬內(nèi)存和段頁(yè)式存儲(chǔ)管理知識(shí)補(bǔ)充

    參考鏈接1

    (以下內(nèi)容來(lái)自電子發(fā)燒友的文章)
    什么是虛擬內(nèi)存?
    在現(xiàn)代操作系統(tǒng)中,多任務(wù)已是標(biāo)配。多任務(wù)并行,大大提升了 CPU 利用率,但卻引出了多個(gè)進(jìn)程對(duì)內(nèi)存操作的沖突問(wèn)題,虛擬內(nèi)存概念的提出就是為了解決這個(gè)問(wèn)題

    操作系統(tǒng)有一塊物理內(nèi)存(中間的部分),有兩個(gè)進(jìn)程(實(shí)際會(huì)更多)P1 和 P2,操作系統(tǒng)偷偷地分別告訴 P1 和 P2,我的整個(gè)內(nèi)存都是你的,隨便用,管夠。可事實(shí)上呢,操作系統(tǒng)只是給它們畫(huà)了個(gè)大餅,這些內(nèi)存說(shuō)是都給了 P1 和 P2,實(shí)際上只給了它們一個(gè)序號(hào)而已。只有當(dāng) P1 和 P2 真正開(kāi)始使用這些內(nèi)存時(shí),系統(tǒng)才開(kāi)始使用輾轉(zhuǎn)挪移,拼湊出各個(gè)塊給進(jìn)程用,P2 以為自己在用 A 內(nèi)存,實(shí)際上已經(jīng)被系統(tǒng)悄悄重定向到真正的 B 去了,甚至,當(dāng) P1 和 P2 共用了 C 內(nèi)存,他們也不知道。(確保了進(jìn)程之間互不影響,也可以讓兩個(gè)進(jìn)程共享同一個(gè)內(nèi)存的內(nèi)容

    操作系統(tǒng)的這種欺騙進(jìn)程的手段,就是虛擬內(nèi)存
    對(duì) P1 和 P2 等進(jìn)程來(lái)說(shuō),它們都以為自己占用了整個(gè)內(nèi)存,而自己使用的物理內(nèi)存的哪段地址,它們并不知道也無(wú)需關(guān)心

    分頁(yè)和頁(yè)表?
    虛擬內(nèi)存是操作系統(tǒng)里的概念,對(duì)操作系統(tǒng)來(lái)說(shuō),虛擬內(nèi)存就是一張張的對(duì)照表,P1 獲取 A 內(nèi)存里的數(shù)據(jù)時(shí)應(yīng)該去物理內(nèi)存的 A 地址找,而找 B 內(nèi)存里的數(shù)據(jù)應(yīng)該去物理內(nèi)存的 C 地址。

    我們知道系統(tǒng)里的基本單位都是 Byte 字節(jié),如果將每一個(gè)虛擬內(nèi)存的 Byte 都對(duì)應(yīng)到物理內(nèi)存的地址,每個(gè)條目最少需要 8字節(jié)(32位虛擬地址->32位物理地址),在 4G 內(nèi)存的情況下,就需要 32GB 的空間來(lái)存放對(duì)照表,那么這張表就大得真正的物理地址也放不下了,于是操作系統(tǒng)引入了頁(yè)(Page)的概念。

    在系統(tǒng)啟動(dòng)時(shí),操作系統(tǒng)將整個(gè)物理內(nèi)存以 4K 為單位,劃分為各個(gè)頁(yè)。之后進(jìn)行內(nèi)存分配時(shí),都以頁(yè)為單位,那么虛擬內(nèi)存頁(yè)對(duì)應(yīng)物理內(nèi)存頁(yè)映射表就大大減小了。4G 內(nèi)存,只需要 8M 的映射表即可,一些進(jìn)程沒(méi)有使用到的虛擬內(nèi)存,也并不需要保存映射關(guān)系,而且Linux 還為大內(nèi)存設(shè)計(jì)了多級(jí)頁(yè)表,可以進(jìn)一頁(yè)減少了內(nèi)存消耗。
    操作系統(tǒng)虛擬內(nèi)存到物理內(nèi)存的映射表,就被稱為頁(yè)表。

    內(nèi)存尋址和內(nèi)存分配?
    我們知道通過(guò)虛擬內(nèi)存機(jī)制每個(gè)進(jìn)程都以為自己占用了全部?jī)?nèi)存,進(jìn)程訪問(wèn)內(nèi)存時(shí),操作系統(tǒng)都會(huì)把進(jìn)程提供的虛擬內(nèi)存地址轉(zhuǎn)換為物理地址,再去對(duì)應(yīng)的物理地址上獲取數(shù)據(jù)。CPU 中有一種硬件,內(nèi)存管理單元 MMU(Memory Management Unit)專門(mén)用來(lái)將翻譯虛擬內(nèi)存地址。CPU 還為頁(yè)表尋址設(shè)置了緩存策略(快表),由于程序的局部性原理,其緩存命中率能達(dá)到 98%。(快表其實(shí)就是一種特殊的高速緩沖寄存器Cache,高速緩存

    以上情況是頁(yè)表內(nèi)存在虛擬地址到物理地址的映射,而如果進(jìn)程訪問(wèn)的物理地址還沒(méi)有被分配,系統(tǒng)則會(huì)產(chǎn)生一個(gè)缺頁(yè)中斷,在中斷處理時(shí),系統(tǒng)切到內(nèi)核態(tài)為進(jìn)程虛擬地址分配物理地址。

    虛擬內(nèi)存的功能:

    • 虛擬內(nèi)存不僅通過(guò)內(nèi)存地址轉(zhuǎn)換解決了多個(gè)進(jìn)程訪問(wèn)內(nèi)存沖突的問(wèn)題,還帶來(lái)更多的益處。
    • 它有助于進(jìn)程內(nèi)存管理,主要體現(xiàn)在:
      內(nèi)存完整性:由于虛擬內(nèi)存對(duì)進(jìn)程的”欺騙”,每個(gè)進(jìn)程都認(rèn)為自己獲取的內(nèi)存是一塊連續(xù)的地址。我們?cè)诰帉?xiě)應(yīng)用程序時(shí),就不用考慮大塊地址的分配,總是認(rèn)為系統(tǒng)有足夠的大塊內(nèi)存即可。
      安全:由于進(jìn)程訪問(wèn)內(nèi)存時(shí),都要通過(guò)頁(yè)表來(lái)尋址,操作系統(tǒng)在頁(yè)表的各個(gè)項(xiàng)目上添加各種訪問(wèn)權(quán)限標(biāo)識(shí)位,就可以實(shí)現(xiàn)內(nèi)存的權(quán)限控制。
    • 通過(guò)虛擬內(nèi)存更容易實(shí)現(xiàn)內(nèi)存和數(shù)據(jù)的共享
      在進(jìn)程加載系統(tǒng)庫(kù)時(shí),總是先分配一塊內(nèi)存,將磁盤(pán)中的庫(kù)文件加載到這塊內(nèi)存中,在直接使用物理內(nèi)存時(shí),由于物理內(nèi)存地址唯一,即使系統(tǒng)發(fā)現(xiàn)同一個(gè)庫(kù)在系統(tǒng)內(nèi)加載了兩次,但每個(gè)進(jìn)程指定的加載內(nèi)存不一樣,系統(tǒng)也無(wú)能為力。
      而在使用虛擬內(nèi)存時(shí),系統(tǒng)只需要將進(jìn)程的虛擬內(nèi)存地址指向庫(kù)文件所在的物理內(nèi)存地址即可。如上文圖中所示,進(jìn)程 P1 和 P2 的 B 地址都指向了物理地址 C。
      而通過(guò)使用虛擬內(nèi)存使用共享內(nèi)存也很簡(jiǎn)單,系統(tǒng)只需要將各個(gè)進(jìn)程的虛擬內(nèi)存地址指向系統(tǒng)分配的共享內(nèi)存地址即可。
    • 虛擬內(nèi)存可以幫進(jìn)程”擴(kuò)充”內(nèi)存
      我們前文提到了虛擬內(nèi)存通過(guò)缺頁(yè)中斷為進(jìn)程分配物理內(nèi)存,內(nèi)存總是有限的,如果所有的物理內(nèi)存都被占用了怎么辦呢?
      Linux 提出 SWAP 的概念,Linux 中可以使用 SWAP 分區(qū),在分配物理內(nèi)存,但可用內(nèi)存不足時(shí),將暫時(shí)不用的內(nèi)存數(shù)據(jù)先放到磁盤(pán)上,讓有需要的進(jìn)程先使用,等進(jìn)程再需要使用這些數(shù)據(jù)時(shí),再將這些數(shù)據(jù)加載到內(nèi)存中,通過(guò)這種”交換”技術(shù),Linux 可以讓進(jìn)程使用更多的內(nèi)存。

    參考鏈接2

    (下面內(nèi)容來(lái)自電子發(fā)燒友的文章)
    各個(gè)進(jìn)程的虛擬內(nèi)存地址相互獨(dú)立。因此,兩個(gè)進(jìn)程空間可以有相同的虛擬內(nèi)存地址,如0x10001000。虛擬內(nèi)存地址和物理內(nèi)存地址又有一定的對(duì)應(yīng)關(guān)系,如圖1所示。對(duì)進(jìn)程某個(gè)虛擬內(nèi)存地址的操作,會(huì)被CPU翻譯成對(duì)某個(gè)具體內(nèi)存地址的操作。

    應(yīng)用程序?qū)?strong>物理內(nèi)存地址一無(wú)所知。它只可能通過(guò)虛擬內(nèi)存地址來(lái)進(jìn)行數(shù)據(jù)讀寫(xiě)。程序中表達(dá)的內(nèi)存地址,也都是虛擬內(nèi)存地址。進(jìn)程對(duì)虛擬內(nèi)存地址的操作,會(huì)被操作系統(tǒng)翻譯成對(duì)某個(gè)物理內(nèi)存地址的操作。由于翻譯的過(guò)程由操作系統(tǒng)全權(quán)負(fù)責(zé),所以應(yīng)用程序可以在全過(guò)程中對(duì)物理內(nèi)存地址一無(wú)所知。

    本質(zhì)上說(shuō),虛擬內(nèi)存地址剝奪了應(yīng)用程序自由訪問(wèn)物理內(nèi)存地址的權(quán)利。進(jìn)程對(duì)物理內(nèi)存的訪問(wèn),必須經(jīng)過(guò)操作系統(tǒng)的審查。因此,掌握著內(nèi)存對(duì)應(yīng)關(guān)系的操作系統(tǒng),也掌握了應(yīng)用程序訪問(wèn)內(nèi)存的閘門(mén)。借助虛擬內(nèi)存地址,操作系統(tǒng)可以保障進(jìn)程空間的獨(dú)立性。只要操作系統(tǒng)把兩個(gè)進(jìn)程的進(jìn)程空間對(duì)應(yīng)到不同的內(nèi)存區(qū)域,就讓兩個(gè)進(jìn)程空間成為“老死不相往來(lái)”的兩個(gè)小王國(guó)。兩個(gè)進(jìn)程就不可能相互篡改對(duì)方的數(shù)據(jù),進(jìn)程出錯(cuò)的可能性就大為減少。

    另一方面,有了虛擬內(nèi)存地址,內(nèi)存共享也變得簡(jiǎn)單。操作系統(tǒng)可以把同一物理內(nèi)存區(qū)域?qū)?yīng)到多個(gè)進(jìn)程空間。這樣,不需要任何的數(shù)據(jù)復(fù)制,多個(gè)進(jìn)程就可以看到相同的數(shù)據(jù)。內(nèi)核和共享庫(kù)的映射,就是通過(guò)這種方式進(jìn)行的。每個(gè)進(jìn)程空間中,最初一部分的虛擬內(nèi)存地址,都對(duì)應(yīng)到物理內(nèi)存中預(yù)留給內(nèi)核的空間。這樣,所有的進(jìn)程就可以共享同一套內(nèi)核數(shù)據(jù)。共享庫(kù)的情況也是類似。對(duì)于任何一個(gè)共享庫(kù),計(jì)算機(jī)只需要往物理內(nèi)存中加載一次,就可以通過(guò)操縱對(duì)應(yīng)關(guān)系,來(lái)讓多個(gè)進(jìn)程共同使用。IPO中的共享內(nèi)存,也有賴于虛擬內(nèi)存地址。

    虛擬內(nèi)存地址和物理內(nèi)存地址的分離,給進(jìn)程帶來(lái)便利性和安全性。但虛擬內(nèi)存地址和物理內(nèi)存地址的翻譯,又會(huì)額外耗費(fèi)計(jì)算機(jī)資源。在多任務(wù)的現(xiàn)代計(jì)算機(jī)中,虛擬內(nèi)存地址已經(jīng)成為必備的設(shè)計(jì)。那么,操作系統(tǒng)必須要考慮清楚,如何能高效地翻譯虛擬內(nèi)存地址

    記錄對(duì)應(yīng)關(guān)系最簡(jiǎn)單的辦法,就是把對(duì)應(yīng)關(guān)系記錄在一張表中。為了讓翻譯速度足夠地快,這個(gè)表必須加載在內(nèi)存中。不過(guò),這種記錄方式驚人地浪費(fèi)。如果樹(shù)莓派1GB物理內(nèi)存的每個(gè)字節(jié)都有一個(gè)對(duì)應(yīng)記錄的話,那么光是對(duì)應(yīng)關(guān)系就要遠(yuǎn)遠(yuǎn)超過(guò)內(nèi)存的空間。由于對(duì)應(yīng)關(guān)系的條目眾多,搜索到一個(gè)對(duì)應(yīng)關(guān)系所需的時(shí)間也很長(zhǎng)。這樣的話,會(huì)讓樹(shù)莓派陷入癱瘓。

    因此,Linux采用了分頁(yè)(paging)的方式來(lái)記錄對(duì)應(yīng)關(guān)系。所謂的分頁(yè),就是以更大尺寸的單位頁(yè)(page)來(lái)管理內(nèi)存。在Linux中,通常每頁(yè)大小為4KB。如果想要獲取當(dāng)前樹(shù)莓派的內(nèi)存頁(yè)大小,可以使用命令:

    getconf PAGE_SIZE

    得到結(jié)果,即內(nèi)存分頁(yè)的字節(jié)數(shù):

    4096

    返回的4096代表每個(gè)內(nèi)存頁(yè)可以存放4096個(gè)字節(jié),即4KB
    Linux把物理內(nèi)存和進(jìn)程空間都分割成頁(yè)。

    內(nèi)存分頁(yè),可以極大地減少所要記錄的內(nèi)存對(duì)應(yīng)關(guān)系。我們已經(jīng)看到,以字節(jié)為單位的對(duì)應(yīng)記錄實(shí)在太多。如果把物理內(nèi)存和進(jìn)程空間的地址都分成頁(yè),內(nèi)核只需要記錄頁(yè)的對(duì)應(yīng)關(guān)系,相關(guān)的工作量就會(huì)大為減少。由于每頁(yè)的大小是每個(gè)字節(jié)的4096倍。因此,內(nèi)存中的總頁(yè)數(shù)只是總字節(jié)數(shù)的四千分之一。對(duì)應(yīng)關(guān)系也縮減為原始策略的四千分之一。分頁(yè)讓虛擬內(nèi)存地址的設(shè)計(jì)有了實(shí)現(xiàn)的可能。

    也就是說(shuō),分頁(yè)其實(shí)分的就是虛擬內(nèi)存地址和物理內(nèi)存地址的對(duì)應(yīng)關(guān)系

    無(wú)論是虛擬頁(yè),還是物理頁(yè),一頁(yè)之內(nèi)的地址都是連續(xù)的。這樣的話,一個(gè)虛擬頁(yè)和一個(gè)物理頁(yè)對(duì)應(yīng)起來(lái),頁(yè)內(nèi)的數(shù)據(jù)就可以按順序一一對(duì)應(yīng)。這意味著,虛擬內(nèi)存地址和物理內(nèi)存地址的末尾部分應(yīng)該完全相同。大多數(shù)情況下,每一頁(yè)有4096個(gè)字節(jié)。由于4096是2的12次方,所以地址最后12位的對(duì)應(yīng)關(guān)系天然成立。我們把地址的這一部分稱為偏移量(offset)。偏移量實(shí)際上表達(dá)了該字節(jié)在頁(yè)內(nèi)的位置。地址的前一部分則是頁(yè)編號(hào)操作系統(tǒng)只需要記錄頁(yè)編號(hào)的對(duì)應(yīng)關(guān)系(用的頁(yè)表頁(yè)號(hào)對(duì)應(yīng)虛擬頁(yè),頁(yè)框號(hào)/內(nèi)存塊號(hào)對(duì)應(yīng)物理頁(yè))。

    內(nèi)存分頁(yè)制度的關(guān)鍵,在于管理進(jìn)程空間頁(yè)(虛擬頁(yè))和物理頁(yè)的對(duì)應(yīng)關(guān)系。操作系統(tǒng)把對(duì)應(yīng)關(guān)系記錄在分頁(yè)表(page table)(即頁(yè)表)中。這種對(duì)應(yīng)關(guān)系讓上層的抽象內(nèi)存和下層的物理內(nèi)存分離,從而讓Linux能靈活地進(jìn)行內(nèi)存管理。由于每個(gè)進(jìn)程會(huì)有一套虛擬內(nèi)存地址,那么每個(gè)進(jìn)程都會(huì)有一個(gè)分頁(yè)表。

    參考鏈接3

    操作系統(tǒng)——段頁(yè)式內(nèi)存管理與虛擬內(nèi)存

    在虛擬內(nèi)存中分段、建立段表、將虛擬頁(yè)映射到空閑物理頁(yè)框,建立頁(yè)表。

    1.如何將段和頁(yè)結(jié)合在一起

    在對(duì)內(nèi)存進(jìn)行使用的過(guò)程中,用戶更希望程序以段的形式被放入內(nèi)存,這樣符合用戶的使用習(xí)慣,譬如找內(nèi)存中“代碼段的第40條指令”。而內(nèi)存更希望將自己等分成若干頁(yè),可以避免因內(nèi)存碎片導(dǎo)致的內(nèi)存利用效率的降低

    為了同時(shí)滿足用戶和內(nèi)存的要求,操作系統(tǒng)需要一種中間結(jié)構(gòu)來(lái)完成段與頁(yè)機(jī)制的統(tǒng)一,這就是虛擬內(nèi)存

    虛擬內(nèi)存是一個(gè)抽象的概念,本身并不存在,它是一連串的虛擬地址構(gòu)成的。
    當(dāng)程序分段后,從虛擬內(nèi)存上分割出相應(yīng)的分區(qū)與各段建立映射關(guān)系,完成分段機(jī)制;(段表:程序段號(hào)段在虛擬內(nèi)存中的起始地址段的長(zhǎng)度
    再將虛擬內(nèi)存分割成頁(yè),將這些頁(yè)放在頁(yè)框中,并建立頁(yè)和頁(yè)框的映射,完成分頁(yè)機(jī)制(頁(yè)表:頁(yè)號(hào)頁(yè)框號(hào)/內(nèi)存塊號(hào))。

    2.段頁(yè)結(jié)合時(shí)進(jìn)程對(duì)內(nèi)存的使用

    提出了虛擬內(nèi)存的概念后,我們已經(jīng)能夠?qū)⒎侄螜C(jī)制和分頁(yè)機(jī)制有機(jī)地結(jié)合在一起了。現(xiàn)在又要引出兩個(gè)問(wèn)題?程序又是如何放置到內(nèi)存中去的了?又是如何得以正確執(zhí)行的了?

    當(dāng)一個(gè)程序想要放入內(nèi)存,會(huì)經(jīng)歷以下的步驟:

    (1)在虛擬內(nèi)存中劃分區(qū)域,將程序分段載入到虛擬內(nèi)存中,其實(shí)就是建立了程序段虛擬內(nèi)存各個(gè)分區(qū)間的映射關(guān)系,將這種映射關(guān)系放到段表中,記錄各段與虛擬內(nèi)存的映射關(guān)系。

    (2)將虛擬內(nèi)存中的各段打散分成頁(yè),然后建立頁(yè)表,記錄虛擬頁(yè)號(hào)物理頁(yè)框號(hào)/內(nèi)存塊號(hào)之間的映射關(guān)系。

    看個(gè)例子(邏輯地址、虛擬地址、物理地址)

    以指令“call 40”為例,邏輯地址40。設(shè)代碼段為第一個(gè)代碼段,頁(yè)面大小為100(頁(yè)面大小和頁(yè)框大小相同)。
    段號(hào)為0,找到該段在虛擬內(nèi)存中的起始地址為1000,偏移量(邏輯地址)是40,1000+40=1040,這是在虛擬內(nèi)存中的地址
    再用1040除以頁(yè)面大小100,得到虛擬頁(yè)號(hào)為10,查找頁(yè)表發(fā)現(xiàn)對(duì)應(yīng)的物理頁(yè)框號(hào)為5,那么實(shí)際內(nèi)存地址為5*100+40=540,就是“mov 1, [300]”指令。

    只要將特定的寄存器(LDTR、CR3)的值設(shè)置為正確段表初始地址頁(yè)表初始地址,執(zhí)行每條指令時(shí)MMU都會(huì)自動(dòng)完成上述地址轉(zhuǎn)換過(guò)程。

    虛擬內(nèi)存和虛擬存儲(chǔ)器的區(qū)別?

    參考鏈接4、5

    參考鏈接
    電子發(fā)燒友的文章

    一、虛擬內(nèi)存(操作系統(tǒng)筆記中的內(nèi)容)
    windows下的虛擬內(nèi)存其實(shí)是借用磁盤(pán)空間假裝它是內(nèi)存,當(dāng)應(yīng)用訪問(wèn)虛擬內(nèi)存地址的時(shí)候,如果內(nèi)存管理器發(fā)現(xiàn)對(duì)應(yīng)的物理地址在磁盤(pán)中,那內(nèi)存管理器就會(huì)將這部分信息從磁盤(pán)中加載回內(nèi)存中。

    (以下的內(nèi)容來(lái)自操作系統(tǒng)筆記中的3.4.3 虛擬存儲(chǔ)技術(shù)
    虛擬內(nèi)存:
    在程序裝入(載入)時(shí),可以將程序中很快會(huì)用到的部分裝入內(nèi)存,暫時(shí)用不到的部分留在外存,就可以讓程序開(kāi)始執(zhí)行了;
    在程序執(zhí)行過(guò)程中,當(dāng)所訪問(wèn)的信息不在內(nèi)存時(shí),由操作系統(tǒng)負(fù)責(zé)將所需信息從外存調(diào)入內(nèi)存,然后繼續(xù)執(zhí)行程序;(外存–>內(nèi)存)
    若內(nèi)存空間不夠,由操作系統(tǒng)負(fù)責(zé)將內(nèi)存中暫時(shí)用不到的信息換出到外存;(內(nèi)存–>外存)
    在操作系統(tǒng)的管理下,在用戶看來(lái)似乎有一個(gè)比實(shí)際內(nèi)存大得多的存儲(chǔ)器,這就是虛擬存儲(chǔ)器

    如何實(shí)現(xiàn)虛擬內(nèi)存技術(shù)?
    要用到操作系統(tǒng)提供的兩個(gè)功能:請(qǐng)求調(diào)頁(yè)功能頁(yè)面置換功能

    二、虛擬存儲(chǔ)器(也叫虛擬內(nèi)存???)(牛客的視頻課中的內(nèi)容)
    更像是一種機(jī)制,這種機(jī)制在有的書(shū)稱為虛擬內(nèi)存,有的書(shū)稱為虛擬存儲(chǔ)器,但是這不重要,重要的是其中的原理、核心。

    虛擬內(nèi)存是硬件異常、硬件地址翻譯、主存、磁盤(pán)文件和內(nèi)核文件的完美交互,它為每個(gè)進(jìn)程提供了一個(gè)大的、一致的、私有的地址空間

    通過(guò)一個(gè)很清晰的機(jī)制,虛擬內(nèi)存提供了三個(gè)重要的能力:
    1)它將主存看成是一個(gè)存儲(chǔ)在磁盤(pán)上的地址空間的高速緩存,在主存中只保存活動(dòng)區(qū)域,并根據(jù)需要在磁盤(pán)和主存之間來(lái)回傳送數(shù)據(jù),通過(guò)這種方式,它高效地使用了主存;
    2)它為每個(gè)進(jìn)程提供了一致的地址空間,從而簡(jiǎn)化了內(nèi)存管理;
    3)它為每個(gè)進(jìn)程提供了私有的地址空間,從而保護(hù)了每個(gè)進(jìn)程的地址空間不被其他進(jìn)程破壞。

    虛擬內(nèi)存是計(jì)算機(jī)系統(tǒng)內(nèi)存管理的一種技術(shù)。 它使得應(yīng)用程序認(rèn)為它擁有連續(xù)可用的內(nèi)存(一個(gè)連續(xù)完整的地址空間),而實(shí)際上物理內(nèi)存通常被分隔成多個(gè)內(nèi)存碎片,還有部分暫時(shí)存儲(chǔ)在外部磁盤(pán)存儲(chǔ)器上,在需要時(shí)進(jìn)行數(shù)據(jù)交換。

    三、總結(jié)
    虛擬存儲(chǔ)技術(shù):
    借用磁盤(pán)空間假裝它是內(nèi)存,當(dāng)應(yīng)用訪問(wèn)虛擬內(nèi)存地址的時(shí)候,如果內(nèi)存管理器發(fā)現(xiàn)對(duì)應(yīng)的物理地址在磁盤(pán)中,那內(nèi)存管理器就會(huì)將這部分信息從磁盤(pán)(外存)中加載回內(nèi)存中。

    虛擬內(nèi)存:
    操作系統(tǒng)為每個(gè)進(jìn)程提供了一個(gè)大的、一致的、私有的地址空間,叫虛擬內(nèi)存地址,或者虛擬地址空間
    1)在主存中只保存活動(dòng)區(qū)域,并根據(jù)需要在磁盤(pán)和主存之間來(lái)回傳送數(shù)據(jù),通過(guò)這種方式,它高效地使用了主存;
    2)它為每個(gè)進(jìn)程提供了一致的地址空間,從而簡(jiǎn)化了內(nèi)存管理;
    3)它為每個(gè)進(jìn)程提供了私有的地址空間,從而保護(hù)了每個(gè)進(jìn)程的地址空間不被其他進(jìn)程破壞。

    7.(5和6的)總結(jié)☆☆☆☆☆

    7.1 虛擬內(nèi)存的提出是為了解決什么問(wèn)題?

    操作系統(tǒng)中有個(gè)概念叫并行,就是多核處理器中每個(gè)核都處理一個(gè)進(jìn)程,這些進(jìn)程是同時(shí)進(jìn)行的,那么就會(huì)有多個(gè)進(jìn)程對(duì)內(nèi)存操作的沖突問(wèn)題,而虛擬內(nèi)存概念的提出就是為了解決這個(gè)問(wèn)題。

    7.2 虛擬內(nèi)存的原理解釋

    首先,每個(gè)進(jìn)程都有一個(gè)虛擬地址空間(但同一個(gè)進(jìn)程下的不同線程共用一個(gè)虛擬地址空間),這樣就確保了進(jìn)程之間互不影響
    程序中表達(dá)的內(nèi)存地址,也都是虛擬內(nèi)存地址。進(jìn)程對(duì)虛擬內(nèi)存地址的操作,會(huì)被操作系統(tǒng)翻譯成對(duì)某個(gè)物理內(nèi)存地址的操作。由于翻譯的過(guò)程由操作系統(tǒng)全權(quán)負(fù)責(zé),所以應(yīng)用程序可以在全過(guò)程中對(duì)物理內(nèi)存地址一無(wú)所知

    本質(zhì)上說(shuō),虛擬內(nèi)存地址剝奪了應(yīng)用程序自由訪問(wèn)物理內(nèi)存地址的權(quán)利。進(jìn)程對(duì)物理內(nèi)存的訪問(wèn),必須經(jīng)過(guò)操作系統(tǒng)的審查。因此,掌握著內(nèi)存對(duì)應(yīng)關(guān)系的操作系統(tǒng),也掌握了應(yīng)用程序訪問(wèn)內(nèi)存的閘門(mén)。借助虛擬內(nèi)存地址,操作系統(tǒng)可以保障進(jìn)程空間的獨(dú)立性。只要操作系統(tǒng)把兩個(gè)進(jìn)程的進(jìn)程空間對(duì)應(yīng)到不同的內(nèi)存區(qū)域,就讓兩個(gè)進(jìn)程空間成為“老死不相往來(lái)”的兩個(gè)小王國(guó)。兩個(gè)進(jìn)程就不可能相互篡改對(duì)方的數(shù)據(jù),進(jìn)程出錯(cuò)的可能性就大為減少。

    操作系統(tǒng)有一塊物理內(nèi)存(中間的部分),有兩個(gè)進(jìn)程(實(shí)際會(huì)更多)P1 和 P2,操作系統(tǒng)偷偷地分別告訴 P1 和 P2,我的整個(gè)內(nèi)存都是你的,隨便用,管夠。可事實(shí)上呢,操作系統(tǒng)只是給它們畫(huà)了個(gè)大餅,這些內(nèi)存說(shuō)是都給了 P1 和 P2,實(shí)際上只給了它們一個(gè)序號(hào)而已。只有當(dāng) P1 和 P2 真正開(kāi)始使用這些內(nèi)存時(shí),系統(tǒng)才開(kāi)始使用輾轉(zhuǎn)挪移,拼湊出各個(gè)塊給進(jìn)程用,P2 以為自己在用 A 內(nèi)存,實(shí)際上已經(jīng)被系統(tǒng)悄悄重定向到真正的 B 去了;甚至,當(dāng) P1 和 P2 共用了 C 內(nèi)存,他們也不知道。

    操作系統(tǒng)的這種欺騙進(jìn)程的手段,就是虛擬內(nèi)存。對(duì) P1 和 P2 進(jìn)程來(lái)說(shuō),它們都以為自己占用了整個(gè)內(nèi)存,而自己使用的物理內(nèi)存的哪段地址,它們并不知道,也無(wú)需關(guān)心。

    虛擬內(nèi)存是操作系統(tǒng)里的概念,對(duì)操作系統(tǒng)來(lái)說(shuō),虛擬內(nèi)存就是一張張的對(duì)照表
    P1 獲取 A 內(nèi)存里的數(shù)據(jù)時(shí)應(yīng)該去物理內(nèi)存的 A 地址找,而找 B 內(nèi)存里的數(shù)據(jù)應(yīng)該去物理內(nèi)存的 C 地址。(這就是邏輯地址和物理地址的一個(gè)對(duì)應(yīng)關(guān)系

    此外,由于每個(gè)進(jìn)程都一個(gè)虛擬地址空間,所以兩個(gè)進(jìn)程可以有相同的虛擬內(nèi)存地址,但經(jīng)過(guò)地址轉(zhuǎn)換后不一定指向同一塊物理內(nèi)存

    7.3 分頁(yè)和頁(yè)表

    我們知道系統(tǒng)里的基本單位都是 Byte 字節(jié),如果將每一個(gè)虛擬內(nèi)存的 Byte 都對(duì)應(yīng)到物理內(nèi)存的地址,每個(gè)條目最少需要 8字節(jié)(32位虛擬地址->32位物理地址),在 4G 內(nèi)存的情況下,就需要 32GB 的空間來(lái)存放對(duì)照表,那么這張表就大得真正的物理地址也放不下了,于是操作系統(tǒng)引入了頁(yè)(Page)的概念。

    在系統(tǒng)啟動(dòng)時(shí),操作系統(tǒng)將整個(gè)物理內(nèi)存以 4K 為單位,劃分為各個(gè)頁(yè)。之后進(jìn)行內(nèi)存分配時(shí),都以頁(yè)為單位,那么虛擬內(nèi)存頁(yè) 和 物理內(nèi)存頁(yè) 的映射表就大大減小了。
    4G 內(nèi)存,只需要 8M 的映射表即可
    32位系統(tǒng)的內(nèi)存是4G = 2^32
    每頁(yè)是4K = 2^12
    所以一共有2^20個(gè)頁(yè),每個(gè)頁(yè)最少占8個(gè)字節(jié)B
    所以就是8M = 2^3 * 2^20

    并且一些進(jìn)程沒(méi)有使用到的虛擬內(nèi)存,也并不需要保存映射關(guān)系,此外Linux 還為大內(nèi)存設(shè)計(jì)了多級(jí)頁(yè)表,可以進(jìn)一頁(yè)減少了內(nèi)存消耗。

    虛擬內(nèi)存物理內(nèi)存的映射表,就被稱為頁(yè)表,即頁(yè)表記錄的是虛擬頁(yè)號(hào)頁(yè)框號(hào)/內(nèi)存塊號(hào)的對(duì)應(yīng)關(guān)系。

    無(wú)論是虛擬頁(yè),還是物理頁(yè),一頁(yè)之內(nèi)的地址都是連續(xù)的。這樣的話,一個(gè)虛擬頁(yè)和一個(gè)物理頁(yè)對(duì)應(yīng)起來(lái),頁(yè)內(nèi)的數(shù)據(jù)就可以按順序一一對(duì)應(yīng)。

    由于每個(gè)進(jìn)程會(huì)有一套虛擬內(nèi)存地址,那么每個(gè)進(jìn)程都會(huì)有一個(gè)分頁(yè)表

    7.4 虛擬內(nèi)存地址(邏輯地址)–>物理地址 (快表、缺頁(yè)中斷)

    我們知道通過(guò)虛擬內(nèi)存機(jī)制,每個(gè)進(jìn)程都以為自己占用了全部?jī)?nèi)存,進(jìn)程訪問(wèn)內(nèi)存時(shí),操作系統(tǒng)都會(huì)把進(jìn)程提供的虛擬內(nèi)存地址轉(zhuǎn)換為物理地址,再去對(duì)應(yīng)的物理地址上獲取數(shù)據(jù)。CPU 中有一種硬件,內(nèi)存管理單元 MMU(Memory Management Unit)專門(mén)用來(lái)翻譯虛擬內(nèi)存地址

    CPU 還為頁(yè)表尋址設(shè)置了緩存策略(快表),由于程序的局部性原理,其緩存命中率能達(dá)到 98%。(快表其實(shí)就是一種特殊的高速緩沖寄存器Cache,高速緩存)

    以上情況是頁(yè)表內(nèi)存在虛擬地址到物理地址的映射,而如果進(jìn)程訪問(wèn)的物理地址還沒(méi)有被分配,系統(tǒng)則會(huì)產(chǎn)生一個(gè)缺頁(yè)中斷,在中斷處理時(shí),系統(tǒng)切到內(nèi)核態(tài)為進(jìn)程提供的虛擬地址分配物理地址。

    7.5 虛擬內(nèi)存的功能

    • 解決了多個(gè)進(jìn)程訪問(wèn)內(nèi)存沖突的問(wèn)題;
    • 內(nèi)存完整性:由于虛擬內(nèi)存對(duì)進(jìn)程的”欺騙”,讓每個(gè)進(jìn)程都認(rèn)為自己獲取的內(nèi)存是一塊連續(xù)的地址,并且內(nèi)存足夠大;
    • 安全:由于進(jìn)程訪問(wèn)內(nèi)存時(shí),都要通過(guò)頁(yè)表來(lái)尋址,操作系統(tǒng)在頁(yè)表的各個(gè)項(xiàng)目上添加各種訪問(wèn)權(quán)限標(biāo)識(shí)位,就可以實(shí)現(xiàn)內(nèi)存的訪問(wèn)權(quán)限控制
      虛擬內(nèi)存地址和物理內(nèi)存地址的分離,給進(jìn)程帶來(lái)便利性和安全性
    • 更容易實(shí)現(xiàn)內(nèi)存和數(shù)據(jù)的共享,如上文圖中所示,進(jìn)程 P1 和 P2 的 B 地址都指向了物理地址 C。(分段的優(yōu)點(diǎn):實(shí)現(xiàn)信息的共享和保護(hù)
      操作系統(tǒng)可以把同一物理內(nèi)存區(qū)域?qū)?yīng)到多個(gè)進(jìn)程空間。這樣,不需要任何的數(shù)據(jù)復(fù)制,多個(gè)進(jìn)程就可以看到相同的數(shù)據(jù)
    • 可以幫進(jìn)程”擴(kuò)充”內(nèi)存,利用交換技術(shù),在內(nèi)存吃緊的時(shí)候把暫時(shí)用不到的數(shù)據(jù)換出到外存中;(裝Linux系統(tǒng)的時(shí)候有一步是設(shè)置交換分區(qū)的大小)

    7.6 段頁(yè)式內(nèi)存管理與虛擬內(nèi)存☆☆☆

    直接看上面參考鏈接3的全部?jī)?nèi)容,主要配合例子來(lái)理解一下。

    C++面試寶典–> 1.2 C++內(nèi)存 和 第2章 操作系統(tǒng)

    E:\找工作\C++八股文\C面試寶典完整版最最最新.pdf
    視頻課中從01:10:39開(kāi)始

    5.7 名稱空間、模板

    補(bǔ)充:內(nèi)存對(duì)齊/字節(jié)對(duì)齊

    (視頻課中從01:28:45開(kāi)始)

    為什么要有內(nèi)存對(duì)齊,因?yàn)榧尤隒PU每次固定的讀4個(gè)字節(jié),這樣可以用空間來(lái)?yè)Q取時(shí)間。

    對(duì)齊模數(shù)必須是2的整數(shù)次冪。

    內(nèi)存對(duì)齊的規(guī)則:

  • 第一個(gè)成員必須是從0位置開(kāi)始偏移;
  • 下面的成員從 成員的大小 和 對(duì)齊模數(shù)相比 較小的那個(gè)數(shù)的整數(shù)倍 的地方開(kāi)始;
    如果成員是結(jié)構(gòu)體變量,就把它里面最大的成員拿出來(lái)和對(duì)齊模數(shù)作比較,取小的那個(gè)的整數(shù)倍;
  • 最后要對(duì)結(jié)構(gòu)體整體進(jìn)行對(duì)齊,整個(gè)結(jié)構(gòu)體的大小應(yīng)該是:成員中最大的那個(gè)(成員中如果有結(jié)構(gòu)體變量,依然是把它里面最大的成員拿出來(lái))和對(duì)齊模數(shù)相比,取小的那個(gè)的整數(shù)倍。
  • 示例:

    #include<iostream> using namespace std; //#pragma pack(show) //默認(rèn)的對(duì)齊模數(shù)是8 //#pragma pack(1) //如果把對(duì)齊模數(shù)改為1,就相當(dāng)于不存在內(nèi)存對(duì)齊了,結(jié)果就是所有的字節(jié)數(shù)加在一起的總和struct Student{//對(duì)齊模數(shù)是8int a; //0 ~ 3float b; //4 ~ 7 float大小是4,4和8相比,4小,從4的整數(shù)倍開(kāi)始char c1; //8 ~ 8 15 char大小是1,1和8相比,1小,從1的整數(shù)倍開(kāi)始double d; //9 16 ~ 23 double大小是8,8和8相比,8小,從8的整數(shù)倍開(kāi)始(所以把9改成16,上面的8改成15//最后,最大的8和對(duì)齊模數(shù)8相比,8小,所以整個(gè)結(jié)構(gòu)體的大小是8的整數(shù)倍,結(jié)果是24 }; struct Student2{//對(duì)齊模數(shù)是8int a; //0 ~ 3 7Student stu;//4 8 ~ 31 結(jié)構(gòu)體中最大的是8,8和8相比,8小,所以從8的整數(shù)倍開(kāi)始(把4改成8,上面的3改成7double d; //32 ~ 39 double大小是8,8和8相比,8小,所以從8的整數(shù)倍開(kāi)始char e; //40 ~ 40 47 char的大小是1,1和8相比,1小,所以從1的整數(shù)倍開(kāi)始//最后,最大的8和對(duì)齊模數(shù)8相比,8小,所以整個(gè)結(jié)構(gòu)體的大小是8的整數(shù)倍,結(jié)果是48(所以上面的40改成47 }; int main(){cout << "float的大小:" << sizeof(float) << endl;//4cout << "double的大小:" << sizeof(double) << endl;//8cout << "int的大小:" << sizeof(int) << endl;//4cout << "char的大小:" << sizeof(char) << endl;//1cout << "結(jié)構(gòu)體Student的大小:" << sizeof(Student) << endl;//24 如果把對(duì)齊模數(shù)改為1,結(jié)果是17cout << "結(jié)構(gòu)體Student2的大小:" << sizeof(Student2) << endl;//48 如果把對(duì)齊模數(shù)改為1,結(jié)果是30return 0; }

    名稱空間

    (視頻課中從02:03:00開(kāi)始)
    C++ Primer Plus(嵌入式公開(kāi)課)—第九章 內(nèi)存模型和名稱空間

    作用域解析運(yùn)算符(兩個(gè)冒號(hào)::)

    它的優(yōu)先級(jí)是運(yùn)算符中等級(jí)最高的,例如cat.Animals::name
    它有三個(gè)作用:1.全局作用域符;2.類作用域符;3名稱空間作用域符

    ::前面沒(méi)有任何內(nèi)容,代表全局作用域符。

    名稱空間

    名稱空間中可以寫(xiě)什么?(變量、函數(shù)、結(jié)構(gòu)體、類…)

    using聲明和using編譯指令

    using聲明和using編譯指令,是用來(lái)簡(jiǎn)化對(duì)名稱空間中名稱的使用

    using聲明:使特定的標(biāo)識(shí)符可用;using std::cout; using std::endl;
    using編譯指令:讓整個(gè)名稱空間中的名稱可用;using namespace std;
    也可以不用using聲明,也不用using編譯指令:std::cout << ""<< std::endl;

    有了using聲明或者using編譯指令,下面再使用時(shí)就不需要再加作用域

    注意:
    using聲明:如果局部變量和using聲明同時(shí)使用會(huì)出現(xiàn)問(wèn)題
    using編譯指令:如果出現(xiàn)同名的變量,不會(huì)報(bào)錯(cuò),使用就近原則。(局部名稱隱藏名稱空間名)

    示例:

    #include<iostream> using namespace std;//讓std這個(gè)名稱空間下的所有名稱都可用namespace fun{int num = 1;double d = 1.1; }namespace fun1{int num = 1;double d = 1.1; }int main(){cout << fun::num << endl;//1int num = 2; using namespace fun; //using編譯:讓fun名稱空間下的所有名稱都可用 如果出現(xiàn)同名的變量,不會(huì)報(bào)錯(cuò),使用就近原則。//using fun::num; //using聲明:只讓fun名稱空間下的變量num可用 如果和局部變量一起用會(huì)出錯(cuò)//有了上面的using聲明或者using編譯指令,下面再使用時(shí)就不需要再加作用域了cout << num << endl; //2cout << num << endl; //有了上面的using聲明,下面再使用時(shí)就不需要再加作用域了cout << d << endl;return 0; }

    模板

    (視頻課中從02:16:45開(kāi)始)

    C++筆記7:C++提高編程1:模板—[函數(shù)模板和類模板]

    C++除了面向?qū)ο缶幊?/strong>思想,還有泛型編程思想。
    泛型編程主要是利用模板技術(shù)來(lái)實(shí)現(xiàn)的。

    函數(shù)模板

    ①函數(shù)模板語(yǔ)法

    語(yǔ)法:

    template<typename T> 函數(shù)聲明或定義

    其中:
    template — 聲明創(chuàng)建模板
    typename — 表面其后面的符號(hào)是一種數(shù)據(jù)類型,可以用class代替
    T — 通用的數(shù)據(jù)類型,名稱可以替換,通常為大寫(xiě)字母

    ②函數(shù)模板和普通函數(shù)的區(qū)別

    函數(shù)模板不允許自動(dòng)類型轉(zhuǎn)換;
    普通函數(shù)能夠自動(dòng)類型轉(zhuǎn)換;(char --> int)

    ③函數(shù)模板調(diào)用規(guī)則

    C++編譯器優(yōu)先考慮普通函數(shù);
    可以通過(guò)空模板實(shí)例參數(shù)列表的語(yǔ)法限定編譯器只能通過(guò)模板匹配;
    函數(shù)模板可以重載;
    如果函數(shù)模板可以產(chǎn)生一個(gè)更好的匹配,那么優(yōu)先選擇模板。

    ④模板實(shí)現(xiàn)機(jī)制及局限性

    函數(shù)模板通過(guò)具體類型產(chǎn)生不同的函數(shù)。

    通過(guò)函數(shù)模板產(chǎn)生的函數(shù)稱為模板函數(shù)

    類模板

    ①類模板基礎(chǔ)語(yǔ)法
    template<typename T>//typename可以用class代替
    ②類模板中成員函數(shù)的創(chuàng)建時(shí)機(jī)

    類模板中成員函數(shù)并不是一開(kāi)始創(chuàng)建,而是在使用的時(shí)候才生成,在替換T后生成。

    #include<iostream> using namespace std;template<class T> class testClass{ public:void func1(){obj.show1();}void fun2(){obj.show2();}T obj; }; class Person1{ public:void show1(){cout << "調(diào)用show1()函數(shù)" << endl;} }; class Person2{ public:void show2(){cout << "調(diào)用show2()函數(shù)" << endl;} }; int main(){testClass<Person1> tc;//testClass<Person2> tc;//編譯錯(cuò)誤tc.func1();return 0; }
    ③類模板做函數(shù)參數(shù)
    ④類模板派生類
    ⑤類模板成員函數(shù)類內(nèi)實(shí)現(xiàn)
    ⑥類模板成員函數(shù)類外實(shí)現(xiàn)
    ⑦類模板分文件編寫(xiě)(類模板文件 .hpp)

    把類的聲明(.h)和實(shí)現(xiàn)(.cpp)寫(xiě)在一起放到.hpp文件中,一看.hpp文件就知道是類模板文件

    ⑧模板類碰到友元函數(shù)
    ⑨模板案例—數(shù)組類封裝

    5.8 STL(標(biāo)準(zhǔn)模板庫(kù))

    C++筆記8:C++提高編程2:STL—標(biāo)準(zhǔn)模板庫(kù)


    SRL六大組件:容器、算法、迭代器、仿函數(shù)、適配器、空間配置器
    容器:各種數(shù)據(jù)結(jié)構(gòu),vector、list、deque、set、map,用來(lái)存放數(shù)據(jù),是一種類模板
    算法:各種常用的算法,sort、find、copy、for_each,是一種函數(shù)模板
    迭代器:相當(dāng)于指針,是一種將operator*,operator->,operator++,operator–等指針相關(guān)操作予以重載的類模板(運(yùn)算符重載?);
    仿函數(shù):重載函數(shù)調(diào)用運(yùn)算符()的類或者類模板;
    適配器:用來(lái)修飾容器、仿函數(shù)、迭代器的接口
    空間配置器:負(fù)責(zé)空間的配置與管理;比如vector容器的擴(kuò)容就是這個(gè)空間配置器來(lái)完成的。

    容器:序列式容器(vector、deque、list)、關(guān)聯(lián)式容器(map、set);
    算法:質(zhì)變算法(拷貝、替換、刪除)、非質(zhì)變算法(查找、計(jì)數(shù)、遍歷);
    迭代器:輸入迭代器(只讀)、輸出迭代器(只寫(xiě))、前向迭代器、雙向迭代器、隨機(jī)訪問(wèn)迭代器。

    vector擴(kuò)容:

    size()是容器中的元素個(gè)數(shù)、capacity()是容器的容量;
    reserve(int len);//預(yù)留len個(gè)元素長(zhǎng)度;
    vector與普通數(shù)組區(qū)別:數(shù)組是靜態(tài)空間,而vector可以動(dòng)態(tài)擴(kuò)展。
    (補(bǔ)充:動(dòng)態(tài)擴(kuò)展并不是在原空間之后續(xù)接新空間,而是找更大的內(nèi)存空間,然后將原數(shù)據(jù)拷貝至新空間,釋放原空間;并且原有的迭代器會(huì)失效。
    另外,vector容器的迭代器是支持隨機(jī)訪問(wèn)的迭代器!!!

    總結(jié) 常用容器的排序的區(qū)別:


    主要看下面兩個(gè)地方的總結(jié):
    我的C++八股文中的筆記9最大的收獲
    C++筆記8:C++提高編程2:STL—標(biāo)準(zhǔn)模板庫(kù)中的☆☆☆總結(jié) 常用容器的排序的區(qū)別

    總結(jié):

    0.自定義排序規(guī)則的實(shí)現(xiàn)方式

    自定義排序規(guī)則:(全局函數(shù))

    • mySort0()//內(nèi)置數(shù)據(jù)類型
    • mySort0()//自定義數(shù)據(jù)類型

    自定義排序規(guī)則:(仿函數(shù))

    • mySort2()//內(nèi)置數(shù)據(jù)類型和自定義數(shù)據(jù)類型

    具體代碼:

    //自定義排序規(guī)則:(全局函數(shù)) bool mySort0(int a, int b){//降序if(a > b)return 1;else return 0; } bool C(const Person& p1, const Person& p2){//降序if(p1.age > p2.age)//按年齡降序return 1;else if(p1.age == p2.age){//如果年齡相等,就按身高升序return p1.height < p2.height;}else return 0; } //自定義排序規(guī)則:(仿函數(shù)) class mySort2{ public://重載函數(shù)調(diào)用運(yùn)算符()bool operator()(int a, int b){return a > b;}bool operator()(const Person& p1, const Person& p2) {//constif(p1.age > p2.age)//按年齡降序return 1;else if(p1.age == p2.age){//如果年齡相等,就按身高升序return p1.height < p2.height;}else return 0;} };

    1.vector容器,deque容器;&& 2.list容器

    對(duì)于內(nèi)置數(shù)據(jù)類型:
    如果想自定義排序規(guī)則,可以使用全局函數(shù)和仿函數(shù)和內(nèi)建仿函數(shù)來(lái)實(shí)現(xiàn):

  • 如果用全局函數(shù),那么參數(shù)就寫(xiě)全局函數(shù)名
  • 如果用仿函數(shù),參數(shù)就是類名后面加個(gè)括號(hào),相當(dāng)于是個(gè)利用無(wú)參構(gòu)造創(chuàng)建的匿名類對(duì)象;
  • 也可以直接使用內(nèi)建仿函數(shù)(大于仿函數(shù)greater<>())直接實(shí)現(xiàn)降序排列,需要包含頭文件#include<functional>。
  • 1.vector容器,deque容器: vector<int> v1; sort(v1.begin(), v1.end());//默認(rèn)升序排序 sort(v1.begin(), v1.end(), mySort0);//降序排列 mySort0是一個(gè)全局函數(shù) sort(v1.begin(), v1.end(), mySort2());//降序排列 mySort2()是一個(gè)類名,仿函數(shù) sort(v1.begin(), v1.end(), greater<>());//降序排列,使用內(nèi)建函數(shù)對(duì)象(仿函數(shù)),就不用自己寫(xiě)排序規(guī)則了2.list容器: list<int> L; L.sort();//默認(rèn)升序排序 L.sort(greater<>()); //降序排列,使用內(nèi)建函數(shù)對(duì)象(仿函數(shù)),就不用自己寫(xiě)排序規(guī)則了 L.sort(mySort0);//降序排列 L.sort(mySort2());//降序排列

    對(duì)于自定義數(shù)據(jù)類型:
    如果容器中存放的是自定義數(shù)據(jù)類型,就必須要指明自定義的排序規(guī)則,不能使用默認(rèn)的排序規(guī)則

    1.vector容器,deque容器: vector<Person> v2; //sort(v2.begin(), v2.end());//報(bào)錯(cuò)!!!沒(méi)有指定排序規(guī)則 //sort(v2.begin(), v2.end(), greater<>());//會(huì)報(bào)錯(cuò)!!!不能使用默認(rèn)的排序規(guī)則 sort(v2.begin(), v2.end(), mySort1);//默認(rèn)排序不能用,必須指明排序規(guī)則,mySort1是一個(gè)全局函數(shù) sort(v2.begin(), v2.end(), mySort2());//默認(rèn)排序不能用,必須指明排序規(guī)則,mySort2()是一個(gè)類名,仿函數(shù)2.list容器: list<Person> L2; //L2.sort();//報(bào)錯(cuò)!!!沒(méi)有指定排序規(guī)則 //L2.sort(greater<>());//會(huì)報(bào)錯(cuò)!!!不能使用默認(rèn)的排序規(guī)則 L2.sort(mySort1);//默認(rèn)排序不能用,必須指明排序規(guī)則,mySort1是一個(gè)全局函數(shù) L2.sort(mySort2());//默認(rèn)排序不能用,必須指明排序規(guī)則,mySort2()是一個(gè)類名,仿函數(shù)

    3.set容器,map容器:

    沒(méi)有sort(),因?yàn)榇巳萜鲿?huì)自動(dòng)排序,默認(rèn)是升序,因此可以利用仿函數(shù)實(shí)現(xiàn)自定義排序規(guī)則,不能通過(guò)全局函數(shù)來(lái)實(shí)現(xiàn)。

    對(duì)于內(nèi)置數(shù)據(jù)類型:
    如果想自定義排序規(guī)則,可以使用仿函數(shù)和內(nèi)建仿函數(shù)來(lái)實(shí)現(xiàn):

  • 可以使用仿函數(shù),參數(shù)就是類名,后面不加括號(hào)
  • 也可以直接使用內(nèi)建仿函數(shù)(大于仿函數(shù)greater<>,后面也沒(méi)有括號(hào))直接實(shí)現(xiàn)降序排列,需要包含頭文件#include<functional>。
  • 對(duì)于自定義數(shù)據(jù)類型:
    如果容器中存放的是自定義數(shù)據(jù)類型,在創(chuàng)建容器的時(shí)候就要指明自定義的排序規(guī)則,不能使用默認(rèn)的排序規(guī)則

    注意:這里的排序規(guī)則寫(xiě)的是類名,后面不用加括號(hào),跟上面的vector、deque、list不一樣,注意區(qū)分!!!
    set容器:

    內(nèi)置數(shù)據(jù)類型: set<int> s1;//默認(rèn)升序排序 //set<int,mySort0> s2;//錯(cuò)誤,這里不能用全局函數(shù),只能用仿函數(shù)實(shí)現(xiàn) //set<int,mySort2()> s2;//錯(cuò)誤,這里寫(xiě)的是類名,后面不用加括號(hào) //set<int, greater<>()> s2;//錯(cuò)誤,后面不用加括號(hào) 注意:仿函數(shù)和內(nèi)建仿函數(shù)后面都不用加括號(hào),跟上面的vector、deque、list不一樣,注意區(qū)分: set<int,mySort2> s2;//降序排列 mySort2是一個(gè)類名,后面不用加括號(hào),仿函數(shù) set<int, greater<>> s2;//降序排列,使用內(nèi)建函數(shù)對(duì)象(仿函數(shù)),這里也沒(méi)有括號(hào),跟上面不一樣自定義數(shù)據(jù)類型: //set<Person> s5;//報(bào)錯(cuò)!!!沒(méi)有指定排序規(guī)則 //set<Person, greater<>> s3;//會(huì)報(bào)錯(cuò)!!!不能使用默認(rèn)的排序規(guī)則 //set<Person,mySort1> s3;//錯(cuò)誤,這里不能用全局函數(shù),只能用仿函數(shù)實(shí)現(xiàn) //set<Person,mySort2()> s2;//錯(cuò)誤,這里寫(xiě)的是類名,后面不用加括號(hào) set<Person,mySort2> s3;//如果容器中存儲(chǔ)的是自定義數(shù)據(jù)類型,在創(chuàng)建容器的時(shí)候就要指明自定義的排序規(guī)則 //注意:這里mySort2后面也沒(méi)有括號(hào)!!!

    map容器:

    map<double, double> m1;//默認(rèn)排序規(guī)則---按照Key值從小到大排 map<double, double,MySort2> m2;//自定義排序規(guī)則---在創(chuàng)建容器的時(shí)候就指明排序規(guī)則(按Key值降序) map<double, double, greater<>> m5;//使用內(nèi)建仿函數(shù)(大于仿函數(shù)greater<>()):按Key值降序map<double, Person> m3;//默認(rèn)排序規(guī)則:按Key值升序 map<double, Person,MySort2> m6;//利用仿函數(shù)自定義排序規(guī)則:按Key值降序 map<double, Person, greater<>> m7;//內(nèi)建仿函數(shù)(大于仿函數(shù)greater<>()):按Key值降序

    4.匯總

    默認(rèn)(升序)排序規(guī)則內(nèi)建仿函數(shù)
    默認(rèn)的降序排序規(guī)則全局函數(shù)實(shí)現(xiàn)降序排序規(guī)則仿函數(shù)實(shí)現(xiàn)降序排序規(guī)則寫(xiě)參數(shù)時(shí)加不加括號(hào)
    vector容器、deque容器、list容器
    (內(nèi)置數(shù)據(jù)類型)
    全局函數(shù)后不加括號(hào);類名后面加括號(hào)
    vector容器、deque容器、list容器
    (自定義數(shù)據(jù)類型)
    ××全局函數(shù)后不加括號(hào);類名后面加括號(hào)
    set容器
    (內(nèi)置數(shù)據(jù)類型)
    ×不能用全局函數(shù)實(shí)現(xiàn),只能用仿函數(shù)實(shí)現(xiàn)
    并且是用仿函數(shù)時(shí)類名后面不加括號(hào)
    set容器
    (自定義數(shù)據(jù)類型)
    ×××只能用仿函數(shù)實(shí)現(xiàn)
    并且是用仿函數(shù)時(shí)類名后面不加括號(hào)
    map容器
    (內(nèi)置數(shù)據(jù)類型)

    按照key值從小到大排序

    按照key值從小到大排序
    ×不能用全局函數(shù)實(shí)現(xiàn),只能用仿函數(shù)實(shí)現(xiàn)
    并且是用仿函數(shù)時(shí)類名后面不加括號(hào)
    map容器
    (自定義數(shù)據(jù)類型)

    按照key值從小到大排序

    按照key值從小到大排序
    ×不能用全局函數(shù)實(shí)現(xiàn),只能用仿函數(shù)實(shí)現(xiàn)
    并且是用仿函數(shù)時(shí)類名后面不加括號(hào)

    函數(shù)對(duì)象 & 謂詞

    函數(shù)對(duì)象基本概念:
    重載函數(shù)調(diào)用操作符()的類,其對(duì)象常稱為函數(shù)對(duì)象
    函數(shù)對(duì)象在使用重載的函數(shù)調(diào)用操作符()時(shí),行為類似函數(shù)調(diào)用,所以也叫仿函數(shù)

    注意:函數(shù)對(duì)象(仿函數(shù))是一個(gè)類,不是一個(gè)函數(shù)。(和普通函數(shù)類似,又超出普通函數(shù)的概念)

    謂詞基本概念:
    返回bool類型的仿函數(shù)稱為謂詞
    如果operator()接受一個(gè)參數(shù),那么叫做一元謂詞
    如果operator()接受兩個(gè)參數(shù),那么叫做二元謂詞

    內(nèi)建函數(shù)對(duì)象

    需要引入頭文件:

    #include<functional>

    關(guān)系仿函數(shù)中最常用的就是greater<>大于,
    因?yàn)槟J(rèn)排序規(guī)則都時(shí)升序,想要實(shí)現(xiàn)降序排序規(guī)則,就要是用大于仿函數(shù)greater<>()

    STL—常用算法

    可以看C++筆記9:C++提高編程3:STL—函數(shù)對(duì)象&標(biāo)準(zhǔn)算法中的5、STL—常用算法

    5.9 C++新特性

    見(jiàn)筆記③:牛客校招沖刺集訓(xùn)營(yíng)—C++工程師

    總結(jié)

    以上是生活随笔為你收集整理的笔记②:牛客校招冲刺集训营---C++工程师(面向对象(友元、运算符重载、继承、多态) -- 内存管理 -- 名称空间、模板(类模板/函数模板) -- STL)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    国产一区二区三区免费在线观看 | 91麻豆操 | 又黄又爽的免费高潮视频 | 欧美久久久 | 人人澡人摸人人添学生av | 天天天天爱天天躁 | 久久99精品国产99久久 | www久久| 91精品国产92久久久久 | 在线观av| 亚洲免费观看视频 | 欧美尹人| 91桃色免费观看 | 日韩超碰在线 | 999久久国精品免费观看网站 | 中字幕视频在线永久在线观看免费 | 91视频在线免费看 | 五月婷婷六月丁香 | 91传媒在线播放 | 国产第一页在线观看 | 日日夜夜草 | 午夜精品久久久99热福利 | 日韩av一区二区三区在线观看 | 人人干人人爽 | 99久久久久久国产精品 | 999久久国产精品免费观看网站 | 亚洲香蕉在线观看 | 中文字幕一区二区三区四区久久 | 中文字幕91在线 | 一区二区三区在线不卡 | 天天曰天天爽 | 免费精品视频在线 | 最新不卡av | 夜夜视频欧洲 | 日韩在线激情 | www.黄色片网站 | 欧美国产三区 | 五月在线视频 | 国产精品自拍在线 | 免费视频一二三 | 欧美视频99 | 五月丁香 | 国产精品国产三级国产aⅴ9色 | 99免费在线视频 | av高清一区二区三区 | 亚洲精选视频在线 | 日韩精品一区二区三区不卡 | 久久久久久国产精品 | 精品国产一区二区三区日日嗨 | 日韩av在线不卡 | 亚洲激情久久 | 久草在线精品观看 | 日本精品视频一区二区 | www麻豆视频 | 99爱国产精品 | 一区二区欧美日韩 | 精品二区久久 | 国产精品69av | 日韩视频1区| 不卡视频一区二区三区 | 性色av免费看 | 涩涩网站在线播放 | 欧美日韩在线播放 | 激情欧美xxxx | 久久久久夜色 | 欧美一级片在线观看视频 | 欧美日韩二三区 | 天堂资源在线观看视频 | 黄色网中文字幕 | 一区二区三区不卡在线 | 在线观看aa| 亚洲精品短视频 | 亚洲视频免费视频 | 亚洲精品一区中文字幕乱码 | 国产精品久久久久久一区二区三区 | 精品综合久久 | 欧美在线a视频 | 国产专区视频在线 | 国产精品欧美一区二区 | 色九九在线 | 一级大片在线观看 | 亚洲高清激情 | 亚洲精品a区 | 六月色丁 | 福利在线看片 | 日韩乱码中文字幕 | 免费看一级片 | 四虎成人在线 | 亚洲精品玖玖玖av在线看 | 五月开心六月婷婷 | 国产精品午夜在线观看 | 成人av在线资源 | 欧美一区影院 | 日韩精品一区二区三区视频播放 | 久久免费福利视频 | 国产精品成人一区二区三区吃奶 | 激情婷婷综合 | 精品免费一区 | 99精品视频免费在线观看 | 日韩精品一区电影 | 亚洲成人网av | 99草视频 | 精精国产xxxx视频在线播放 | 大型av综合网站 | 国产又黄又硬又爽 | 五月亚洲| 欧美日韩国产在线精品 | 久久在视频 | 中文字幕你懂的 | 亚洲男男gaygay无套 | 日韩天天操 | 久青草国产在线 | 蜜臀久久99精品久久久无需会员 | 亚洲一区二区三区在线看 | 亚洲最新精品 | 国产专区视频在线观看 | 亚洲粉嫩av| 久久视讯 | 最新中文字幕在线观看视频 | 亚洲va欧美va人人爽春色影视 | 精品久久一级片 | 成人试看120秒 | 久久久精品久久 | 日韩中文字幕在线看 | 伊人国产在线观看 | 久草在线免费资源站 | 免费在线电影网址大全 | 一区二区三区视频在线 | 91av视频在线观看免费 | 黄色com| 97久久精品午夜一区二区 | 99电影456麻豆 | 国产福利91精品一区二区三区 | www.婷婷色 | 免费在线观看av电影 | 91亚洲激情 | 中文字幕免费在线 | 欧美日韩三级在线观看 | 久久久www免费电影网 | 天堂资源在线观看视频 | 成人av电影免费 | 国产理论影院 | 久在线| 国产一区二区视频在线 | 人人爽人人搞 | 久久久久北条麻妃免费看 | 国产精品99精品 | 色婷婷综合视频在线观看 | 超碰人人草人人 | 狠狠ri | 黄色成人在线观看 | av电影免费看 | 在线成人免费 | 超碰在线官网 | 一区二区视频欧美 | 国产日产精品一区二区三区四区 | 国产精品久久久久久久久久99 | 韩日电影在线观看 | 久久精品国产成人精品 | 午夜精品久久久久久久99水蜜桃 | 黄色在线网站噜噜噜 | 日本激情视频中文字幕 | 成人免费在线观看电影 | 97超碰超碰久久福利超碰 | 五月婷婷操 | av资源在线观看 | 国产精品美女在线 | 黄色av影院 | 国产裸体永久免费视频网站 | 日韩免费视频网站 | www夜夜操com | 超碰日韩在线 | 国产欧美精品一区二区三区 | 日韩在线免费看 | 人人射人人 | 欧美成亚洲| 99热在线国产精品 | 69xx视频| 国产999视频在线观看 | 日韩欧美精品在线 | 日日夜夜免费精品视频 | 在线看国产精品 | 天天夜夜操 | 国产成人福利片 | 国产精品2020 | 国产精品亚洲视频 | 综合黄色网 | 日韩在线不卡视频 | 亚洲国产资源 | 国产福利一区二区三区在线观看 | 国产99久久久国产精品成人免费 | 免费日韩一区 | 日本久久91 | 蜜臀av免费一区二区三区 | 欧美精品资源 | 色婷婷精品大在线视频 | 美女国产免费 | 国产精品久久久久久久久大全 | 日韩大片在线免费观看 | 日韩黄色一区 | 精品国产一区二区三区四区在线观看 | av国产网站| 久草资源免费 | 97av在线视频免费播放 | 久久久精品免费观看 | 黄色精品国产 | 这里只有精品视频在线观看 | 毛片美女网站 | av看片网 | 免费日韩一区二区三区 | 精品免费在线视频 | 国产一级片不卡 | 九七人人干 | 国产精品久久久久久久久婷婷 | 国产欧美精品在线观看 | 手机av在线不卡 | 久草在线播放视频 | 国产一二三区av | 成人毛片在线观看 | 日韩欧美一区二区在线 | 人人澡人| 97色涩 | 久久人人添人人爽添人人88v | 久久成人欧美 | 亚洲成人一二三 | 少妇18xxxx性xxxx片 | 久久免费成人网 | 日韩高清精品免费观看 | 成人av亚洲 | 亚洲少妇激情 | 欧美亚洲精品一区 | 久草视频在线看 | 日韩va欧美va亚洲va久久 | 91在线精品一区二区 | 亚洲欧美在线视频免费 | 亚洲涩涩涩 | 亚洲天堂香蕉 | 91精品老司机久久一区啪 | 国产成人精品av在线 | 国产一二三在线视频 | 国产精品精品国产婷婷这里av | 日日弄天天弄美女bbbb | 免费在线日韩 | 五月婷婷丁香网 | 日韩精品在线观看av | 久久国产精品久久w女人spa | 美女免费视频观看网站 | 在线免费av网站 | 99999精品| 天堂网在线视频 | japanesexxx乱女另类 | 中文字幕观看av | 国内精品久久久久久久影视简单 | 99夜色| 在线观看精品一区 | 国产 一区二区三区 在线 | 欧美日韩国产一二三区 | 亚洲午夜小视频 | 久久这里| 在线看岛国av| 中文字幕一区二区三区在线播放 | 久久久久久免费 | 欧美日韩国产区 | 一区二区三区在线免费播放 | 免费视频一级片 | 国产亚州av | 久久久久综合精品福利啪啪 | 精品人妖videos欧美人妖 | 麻豆久久久久久久 | 色偷偷88888欧美精品久久 | 欧美午夜a| 在线观看完整版 | 久久精久久精 | 国产韩国日本高清视频 | 乱男乱女www7788 | 欧美巨大荫蒂茸毛毛人妖 | 丁香九月婷婷综合 | 又黄又刺激 | 成人a免费看 | 日韩在线观看你懂的 | 久操视频在线免费看 | 国产精品网站一区二区三区 | 国产成人精品a | 免费观看一级视频 | 中文亚洲欧美日韩 | 综合久久五月天 | 日韩在线电影 | av片在线观看 | 亚洲免费永久精品国产 | 欧美做受xxx | 日日碰狠狠添天天爽超碰97久久 | 在线观看亚洲精品视频 | 久久成人国产精品免费软件 | 国产又粗又猛又黄又爽的视频 | av大全在线观看 | 蜜臀av一区 | 国产精品福利一区 | 少妇bbw搡bbbb搡bbbb | 日韩视频二区 | 日本最大色倩网站www | 天天摸天天弄 | 伊人国产视频 | 亚洲婷婷在线视频 | 欧美极品少妇xbxb性爽爽视频 | 99精品国产在热久久下载 | 国产精品免费麻豆入口 | 亚洲专区欧美专区 | 久久999精品 | 亚洲国产成人在线 | 久久福利综合 | 99免费视频 | 久久久久久久久久免费 | 天天插天天爱 | 国产精品久久久久久久久免费 | av高清一区二区三区 | 国产无套精品久久久久久 | 免费在线成人av电影 | 亚洲精品免费在线观看视频 | 91麻豆国产福利在线观看 | 日韩精品一区二区三区中文字幕 | 激情久久网 | av亚洲产国偷v产偷v自拍小说 | 中国一级特黄毛片大片久久 | 激情欧美一区二区三区免费看 | 亚洲精品国产精品国 | 精品字幕 | 中文字幕中文字幕在线一区 | 国产精品美女免费视频 | 日日成人网 | 久久视频在线观看中文字幕 | 成 人 黄 色 免费播放 | 亚洲在线看 | 久久在线一区 | 欧美一级日韩三级 | 久久久久久国产精品亚洲78 | 欧美日韩综合在线 | 91欧美日韩国产 | 97超碰在线免费观看 | 日韩电影在线观看一区二区三区 | 国产亚洲精品日韩在线tv黄 | 欧美性免费 | 最新日韩视频 | 免费看av在线 | 黄色特级一级片 | 亚洲小视频在线 | 久草在线免费在线观看 | 综合久久综合久久 | 免费观看黄 | 成人中文字幕+乱码+中文字幕 | 免费观看9x视频网站在线观看 | 久久超碰99 | 国产淫片免费看 | 天天做天天射 | 亚洲日本va午夜在线电影 | 国产精品av电影 | 99在线播放 | 亚洲欧美va | 97夜夜澡人人双人人人喊 | 色网免费观看 | 午夜av激情 | 99精品国产一区二区三区不卡 | 日韩av不卡在线 | 1区2区视频 | 国产成人精品av久久 | 激情动态| 色com网 | 成人毛片一区 | 中文字幕在线高清 | 精品国产伦一区二区三区观看体验 | 久草在线视频精品 | 久久99深爱久久99精品 | 天天性天天草 | 国产亚洲精品美女久久 | 免费观看一级视频 | 亚洲国产中文字幕 | 国产在线看| 五月天丁香 | 天天爽人人爽夜夜爽 | 中文字幕在线免费观看视频 | 久久久激情网 | 在线免费观看亚洲视频 | 国产日韩在线一区 | 久久影院中文字幕 | 色综合久久五月 | 亚洲国产中文字幕在线观看 | 久久精品久久精品久久39 | 国产精品美女毛片真酒店 | 99在线精品免费视频九九视 | 久久久精品一区二区三区 | 99成人在线视频 | 久久午夜精品影院一区 | 日韩成人中文字幕 | 麻豆视频国产在线观看 | 久草视频看看 | 国产特黄色片 | 欧美精品999 | www91在线观看 | 国产亚洲精品无 | 日韩在线 一区二区 | 国产精品免费观看在线 | 日韩黄色av网站 | 夜色成人av | 久久久国产一区二区三区四区小说 | 欧洲精品久久久久毛片完整版 | 天天操天天色综合 | 狠狠狠色丁香婷婷综合久久88 | 久久久av电影 | 91mv.cool在线观看 | 日韩网| 在线国产一区 | 精品在线观看一区二区 | 性色xxxxhd | 四虎最新域名 | 欧美a性 | 日韩丝袜在线 | 日韩伦理片一区二区三区 | 在线电影 一区 | 成人精品视频久久久久 | 国产经典av| 91九色综合 | 免费人人干 | 日韩一区二区三区高清在线观看 | 成人免费在线电影 | 久久免费视屏 | 操操操人人人 | 男女激情麻豆 | 国产欧美精品一区aⅴ影院 99视频国产精品免费观看 | www.黄色小说.com | 91av资源在线 | 亚洲伊人av | 日韩欧美视频一区二区 | 人人草在线观看 | 成年在线观看 | 四虎成人精品永久免费av | 99热国产在线中文 | 亚洲国产字幕 | 中文字幕高清免费日韩视频在线 | 成人av在线直播 | 91精品国产入口 | 亚洲精品色 | v片在线看| 国产精品久久99综合免费观看尤物 | 免费a视频在线观看 | 91日韩精品视频 | 免费在线观看日韩欧美 | 中文字幕亚洲不卡 | 日本中文字幕在线电影 | 亚洲精品白浆高清久久久久久 | 亚洲黄色一级视频 | 一级电影免费在线观看 | 天天在线操 | 国产99视频在线观看 | 91一区啪爱嗯打偷拍欧美 | 成人精品福利 | 中文字幕在线播放第一页 | 免费网站黄 | 久久艹艹| 不卡的av在线播放 | 日本久久电影 | 超碰97免费| 欧美亚洲专区 | 日韩大片在线免费观看 | 综合av在线 | 久久精品国产一区 | 久久草在线免费 | 999久久久久久久久久久 | 国产玖玖在线 | 日韩精品首页 | 日韩在线免费电影 | 摸阴视频 | 国产不卡免费视频 | 国产免费观看久久 | 国产精品亚洲视频 | 日韩免费电影网站 | 亚洲人xxx | 亚洲国产中文字幕在线视频综合 | 国产一二区在线观看 | 免费av的网站 | 国产91综合一区在线观看 | 欧美a级在线免费观看 | 国产婷婷精品 | 国产精品中文字幕在线观看 | 亚洲高清视频在线观看 | 日本不卡一区二区三区在线观看 | 成人91视频| 欧美激情精品久久久久久免费 | 99热99re6国产在线播放 | 美女网站久久 | www久久九 | 亚a在线 | 99久久99久久免费精品蜜臀 | 偷拍精品一区二区三区 | av一级一片| 国产精品久久久久高潮 | 亚洲国产日韩欧美 | 精品久久综合 | 91视频 - 88av | 日本黄色免费在线观看 | 婷五月天激情 | 国产精品字幕 | 一区二区三区四区影院 | 国产专区视频在线 | 成人在线播放免费观看 | 午夜婷婷在线播放 | 天天操狠狠操夜夜操 | 国产三级av在线 | 日韩高清免费观看 | 日韩精品久久一区二区三区 | 中文字幕一区二区三区久久 | 日韩免费成人av | 美女黄频视频大全 | 精品国产久| 欧美乱码精品一区 | 国产一区免费在线 | 高清av不卡| 久久久久久久久久久黄色 | 日韩免费电影网站 | 国产伦精品一区二区三区高清 | 免费黄色看片 | 国产999在线 | 亚洲精品无 | 99热这里只有精品免费 | 欧洲精品码一区二区三区免费看 | 久久久亚洲影院 | 成年人免费在线观看网站 | 2024国产精品视频 | 大片网站久久 | 中文在线8新资源库 | 91在线视频网址 | 国产精品高清在线观看 | 久久久网址 | 婷婷亚洲激情 | 国产亚洲精品电影 | 在线观看的av网站 | 日韩城人在线 | 亚洲成av人片在线观看www | 六月丁香激情网 | 成人免费在线播放 | 日韩精品一区二区三区在线播放 | 最新av中文字幕 | 精品在线看 | 国产一区在线精品 | 在线不卡的av| 精品国产一区二区三区男人吃奶 | 天天干天天做天天操 | 久久艹免费| 国产精品美女久久久久久 | 国产一区二区在线免费 | 在线视频 日韩 | 色福利网站 | 成人午夜剧场在线观看 | 久久精品5| 婷婷在线观看视频 | 欧美日韩一二三四区 | 国产不卡免费 | 中文字幕av日韩 | 在线蜜桃视频 | 狠狠色丁香久久婷婷综合丁香 | 国产精品一区二区麻豆 | 久久精品香蕉视频 | 人人搞人人搞 | 久久久久国产精品www | 最新中文字幕在线播放 | 国产免费看 | 日韩精品国产一区 | 中文欧美字幕免费 | 精品国产一区二区三区日日嗨 | 少妇18xxxx性xxxx片 | 一二区电影 | 91丨porny丨九色| 日日噜噜噜噜夜夜爽亚洲精品 | 国产色爽| 国产99在线播放 | 成人av影视在线 | 欧美日韩一区二区视频在线观看 | 久久精品国产精品亚洲 | 国产一区二区三区黄 | 久久综合狠狠综合 | 国产极品尤物在线 | 久久国产精品久久精品国产演员表 | 伊人天堂av | 婷婷六月天天 | 国产精品久久久精品 | av黄色亚洲 | 日韩精品一区在线播放 | 国产精品久久一区二区三区不卡 | 麻豆一级视频 | 久久综合色8888 | 国产一区二区三区 在线 | 99亚洲国产精品 | 看黄色91| 日韩二三区 | 亚洲激情网站免费观看 | 精品国产免费观看 | 六月丁香六月婷婷 | 久久久久久看片 | 精品国产一区二区三区久久 | 中文字幕在线不卡国产视频 | 国产精品入口66mio女同 | 色av男人的天堂免费在线 | 天堂在线一区二区 | 一区 二区 精品 | 亚洲精品免费视频 | 成人av免费| 久久久综合色 | 午夜国产在线观看 | 欧美极品xxxxx | 久久avav| 人人爽人人片 | 91麻豆免费视频 | 综合网中文字幕 | 精品久久久久久综合日本 | 成年人免费在线观看 | 激情电影影院 | 欧美激情综合色综合啪啪五月 | 黄色小说在线免费观看 | 中文国产字幕在线观看 | 免费看wwwwwwwwwww的视频 久久久久久99精品 91中文字幕视频 | av动态图片 | 久久99国产精品 | 国产亚洲婷婷免费 | 欧美日韩三区二区 | 日韩精品一区二区三区不卡 | 精品福利在线视频 | 91精品国产麻豆 | 婷婷 中文字幕 | 久久久免费电影 | 亚洲国产日韩一区 | 国产精品久久久久久久久大全 | 成人丁香花 | 丁香视频五月 | 91香蕉亚洲精品 | 精品国产一区二区三区蜜臀 | 在线国产一区二区三区 | 欧美天天综合网 | 精产嫩模国品一二三区 | 久久久精品在线观看 | 2019中文最近的2019中文在线 | 在线观看日韩国产 | 免费视频二区 | 91精品国产99久久久久 | 久久亚洲二区 | 国产三级国产精品国产专区50 | 操操综合网 | 成人观看视频 | 97视频在线观看视频免费视频 | 免费福利视频导航 | 欧美日韩国产精品一区二区亚洲 | 97电影在线观看 | 2021国产精品 | 欧美日韩一区久久 | 欧美日韩亚洲在线观看 | 久久国产精品小视频 | 国产中文字幕网 | 日韩精品中文字幕在线播放 | 欧美成人性战久久 | 国产一区二区视频在线播放 | 久久欧美综合 | 成人av影院在线观看 | 国产一级片久久 | 欧美精品小视频 | 日韩在线欧美在线 | 国产精品资源网 | 狠狠色噜噜狠狠狠合久 | 国产成人高清在线 | 国产成人精品三级 | 久久精品中文字幕一区二区三区 | 国产精品一区二区电影 | 日韩中文字幕在线不卡 | 久久久久亚洲精品国产 | 精品国产a| 色多多视频在线观看 | 午夜999| 超碰在线1 | av电影一区二区 | 播五月综合 | 在线观看国产一区 | 看片的网址| 婷婷精品国产一区二区三区日韩 | 99爱精品在线 | www国产亚洲精品久久网站 | 麻豆视频在线免费看 | 亚洲永久av | 黄色亚洲大片免费在线观看 | 久久都是精品 | 欧美一级久久久 | 97超视频| 久久激情五月婷婷 | 久久区二区 | 亚洲视频播放 | 亚洲 欧美日韩 国产 中文 | 亚洲精品资源在线观看 | 国产精品久久久久久久久久久久午夜片 | 狠狠夜夜| 色丁香久久| 成人羞羞视频在线观看免费 | 久久 地址 | 婷婷六月综合亚洲 | 手机在线日韩视频 | 欧美黄色软件 | 日本久久久久久久久 | 综合精品久久久 | 色综合天天天天做夜夜夜夜做 | 欧美视频99 | 国产在线观看你懂的 | 人人玩人人添人人 | 成人禁用看黄a在线 | 久久国产视频网 | 久久久久成人精品亚洲国产 | 激情五月在线观看 | 国产护士hd高朝护士1 | 最近最新中文字幕 | 国产成人在线网站 | 国产美女视频免费 | 天堂av一区二区 | 久久久久久欧美二区电影网 | 激情 一区二区 | 99九九热只有国产精品 | 2023国产精品自产拍在线观看 | 国产精品综合在线观看 | 亚洲精品中文字幕在线观看 | 日日夜夜精品 | 黄色毛片大全 | 久久er99热精品一区二区 | 人人射人人 | 亚洲精品88欧美一区二区 | 五月婷婷激情五月 | 精品国产一区二区三区在线观看 | 欧美日韩三区二区 | www.888av| av免费在线观| 欧美日韩一区二区视频在线观看 | 国产麻豆精品一区二区 | 肉色欧美久久久久久久免费看 | 色综合婷婷久久 | 99精品欧美一区二区三区 | 高潮久久久久久久久 | 91少妇精拍在线播放 | 国产精品12345 | 99热在线观看 | 久久tv | 国产精品福利在线 | 久操免费视频 | 噜噜色官网 | 特级西西www44高清大胆图片 | 黄色av免费 | 亚洲午夜精品久久久久久久久久久久 | 亚洲乱码久久久 | 成人午夜电影免费在线观看 | 91大神免费在线观看 | 在线视频久久 | 亚洲男男gaygay无套 | 人人爽人人爽人人爽 | 欧美在线视频一区二区三区 | 欧美另类亚洲 | 日韩中文在线字幕 | 精品a级片| 国产成a人亚洲精v品在线观看 | 天天干人人 | 狠狠做六月爱婷婷综合aⅴ 日本高清免费中文字幕 | 麻豆视频91 | 在线视频专区 | av一级片 | 久久经典国产视频 | 欧美激情第八页 | va视频在线 | 日本韩国精品一区二区在线观看 | 免费网站黄 | 久久蜜臀一区二区三区av | 国产色中涩 | 国产成人三级在线观看 | 91热爆视频 | 亚洲欧美日韩一区二区三区在线观看 | 激情av五月婷婷 | 欧美天天射| 久久黄网站 | 狠狠色丁香婷婷综合久小说久 | 久久精品韩国 | 精品国模一区二区三区 | 精品专区一区二区 | av解说在线 | 天天综合网入口 | 国产精品久久久久久久av大片 | 国产精品久久一区二区三区不卡 | 欧美日韩在线观看不卡 | 中文字幕在线观看免费高清完整版 | 69欧美视频 | 久草精品视频在线播放 | 91麻豆精品国产自产在线 | 国产专区一 | 四虎欧美 | 99热精品久久 | 成年人免费电影在线观看 | 精品视频久久 | 午夜影院在线观看18 | 黄色av大片 | 91精品久久久久久久99蜜桃 | 国产免费人成xvideos视频 | 久久av中文字幕片 | 日韩在线网 | 久久99精品国产麻豆宅宅 | a成人v在线 | 人人搞人人干 | 免费在线观看国产黄 | 久久中文字幕导航 | 婷婷色5月| 亚洲少妇自拍 | 中文字幕在线观 | 精品亚洲欧美一区 | 五月天婷婷在线播放 | 亚州精品天堂中文字幕 | 成人免费看片网址 | 香蕉视频在线免费 | 亚洲欧美国产精品久久久久 | 亚洲精品乱码久久久久v最新版 | 日韩中文字幕视频在线观看 | 日韩在线观看三区 | 狠狠操欧美 | 亚洲精品乱码久久久久久9色 | 香蕉视频久久 | av网站在线免费观看 | 91成人国产| 国产又粗又硬又长又爽的视频 | 久久精品资源 | 国产午夜精品免费一区二区三区视频 | 国产精品久久久久久久久久久杏吧 | 欧美一级片免费在线观看 | 色狠狠综合天天综合综合 | 黄色app网站在线观看 | 日本精品久久久久影院 | 一级黄色av | 国产福利91精品 | 婷婷去俺也去六月色 | 国产免费a | 免费手机黄色网址 | 精品国产乱码久久久久久1区2匹 | 国产精品麻豆99久久久久久 | 日日碰狠狠躁久久躁综合网 | 麻豆视频在线播放 | 亚洲成人免费在线观看 | 成人黄色在线看 | 日韩丝袜在线观看 | 美女视频黄色免费 | 亚洲91精品在线观看 | 亚洲国产精品第一区二区 | 亚洲www天堂com| 亚洲精品美女在线观看 | 久久精品在线 | 国产区精品在线观看 | 久久短视频| 91精品国产自产在线观看永久 | av夜夜操 | 日韩精品视频在线免费观看 | av手机在线播放 | 国产91精品一区二区绿帽 | 日韩视频一区二区在线观看 | av在线看片 | 久久久国产高清 | 亚洲国产精品视频在线观看 | 久久综合狠狠综合久久综合88 | 欧美精品久久久久a | 欧美日韩精品区 | 日b黄色片| 久久久高清一区二区三区 | 伊人电影在线观看 | 久久久久免费精品视频 | 成人黄色小说视频 | 国产香蕉av | 一本一道久久a久久精品 | 99久久久成人国产精品 | 亚洲人在线 | 在线免费观看麻豆 | 久一久久 | 国产综合香蕉五月婷在线 | 国产精品去看片 | 亚洲黄色影院 | av在线电影免费观看 | 亚洲欧美日本一区二区三区 | 97在线成人 | 在线观看深夜视频 | 99精品国产成人一区二区 | 国产高潮久久 | 日韩在线国产精品 | 欧美日韩99 | 欧美色图p | 国产做爰视频 | av中文字幕在线播放 | 精品一区中文字幕 | 香蕉在线播放 | 黄色小说视频在线 | 久久黄色成人 | 国产99久久久国产精品免费看 | 日韩av在线免费播放 | 黄色特一级片 | 日韩精品久久久久久 | 免费在线观看黄网站 | 亚洲女同videos| 国产精品成人自产拍在线观看 | 欧美一区在线观看视频 | 久久成人精品电影 | 亚洲伊人婷婷 | 日日操天天操夜夜操 | 天天草天天色 | 亚洲九九九在线观看 | 久久成人午夜 | 91精品网站在线观看 | 免费国产黄线在线观看视频 | 国产在线a免费观看 | 欧洲一区精品 | 91爱爱电影 | 日韩精品一区二区在线视频 | 激情五月激情综合网 | 在线成人小视频 | 欧美色插 | 久久久久女人精品毛片 | 免费看黄在线观看 | www国产亚洲精品久久网站 | 欧美日韩一区二区在线观看 | 久草爱视频| av中文资源在线 | 69精品| 992tv在线观看网站 | 黄网在线免费观看 | 狠狠操天天干 | 手机成人在线 | 日韩在线播放欧美字幕 | 亚洲成av人片在线观看无 | 99视频精品在线 | 日韩在线第一 | 欧美男同网站 | 国产精品你懂的在线观看 | 97超碰中文字幕 | 在线观看日韩中文字幕 | 成人久久久精品国产乱码一区二区 | 免费色黄 | 国产一二三四在线观看视频 | 亚洲一区二区三区四区在线视频 | 国产成人亚洲在线观看 | 97视频免费在线 | 亚洲精品美女久久久久 | 日韩小视频网站 | 国产精品久久久777 成人手机在线视频 | 欧美大码xxxx| 日韩字幕| 岛国av在线不卡 | 一区二区三区动漫 | 久久综合五月婷婷 | 久久国产精品久久久久 | 久久高清视频免费 | 久久精品视频播放 | 91系列在线 | 在线亚洲高清视频 | 日韩免费电影一区二区 | 日韩欧美69 | 主播av在线 | 国产成人精品亚洲 | 国产视频久久 | 女人18片 | 久草久草久草久草 | 久久香蕉国产精品麻豆粉嫩av | 尤物九九久久国产精品的分类 | 国产精品美女久久久久久久久久久 | 精品国产乱码久久久久久1区2匹 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 97色视频在线 | 超碰人人做 | 亚洲电影黄色 | 二区三区视频 | www.eeuss影院av撸| 国产第一页在线观看 | 欧美在线观看视频免费 | 亚洲欧美偷拍另类 | 国产亚洲情侣一区二区无 | 亚洲h在线播放在线观看h | 免费av大全 | 亚洲午夜不卡 | 国产91精品欧美 | 日日爽天天爽 | 日韩黄视频 | 一区二区观看 | 欧美午夜寂寞影院 | 99精品视频免费在线观看 | 91尤物在线播放 | www四虎影院 | 国产成人精品亚洲日本在线观看 | 国产91在| 国内三级在线观看 | 国产专区日韩专区 | 狠狠搞,com | 在线一区电影 | 在线有码中文 | 91免费观看国产 | av不卡免费看 | 男女视频久久久 | 国产在线91在线电影 | 日韩精品高清不卡 | 麻豆91在线观看 | 麻豆 videos|