青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 60, 文章 - 0, 評論 - 197, 引用 - 0
數據加載中……

C++ 學習筆記

一   編程設計
     1.將程序劃分為多個子系統,包括子系統間的接口和依賴關系、子系統間的數據流、在各子系統間的來回輸入輸出、以及總的線程模型。

     2.各個子系統的具體細節,包括進一步細分的類、類層次體系、數據結構、算法、特定的線程模型和錯誤處理。

二   設計流程
     1.需求:功能需求和性能需求。
     2.設計步驟
       (1)把程序劃分為通用功能子系統,并明確子系統的接口和交互。
       (2)把這些子系統列在一個表中,并表示出子系統的高層行為或功能、子系統向其它子系統提供的接口,及此子系統使用了其他子系統的哪些接口。
       (3)選擇線程模型:確定使用多少個線程,明確線程的交互并為共享數據指定加鎖機制。
       (4)為每個子系統指定層次體系
       (5)為每個子系統指定類、數據結構、算法和模式
       (6)為每個子系統指定錯誤處理(系統錯誤 + 用戶錯誤),指定是否使用異常

三   C++ 的設計原則
     1.抽象:將接口與實現相分離
     2.重用:代碼重用和思想重用

四   對象關系
     1.has-a 關系(聚集)
     2.is-a  關系(繼承)
     3.組織對象層次體系:
      (1)將類按有意義的功能加以組織。
      (2)將共同的功能放到超類中,從而支持代碼重用。
      (3)避免子類過多的覆蓋父類的功能。

五   重用設計
     1.建立可重用的代碼結構
      (1)避免將無關或邏輯上分離的概念混在一起
      (2)把程序劃分為子系統
      (3)使用類層次體系來分離邏輯概念
      (4)使用聚集來分離邏輯概念
      (5)對通用數據結構和算法使用模板
      (6)提供適當的檢查和防護

六   設計易于使用的接口
     1.開發直觀的接口
     2.不要遺漏必要的功能
     3.提供簡潔的接口
      (1)消除重復的接口
      (2)只提供所需的功能
      (3)適當的限制庫的使用
     4.提供文檔和注釋
      (1)公共的文檔應指定行為,而不是底層實現

七   設計通用的接口
     1.提供多種方法來完成同一功能
     2.提供定制能力

八   協調一般性和通用性
     1.提供多個接口
     2.優化常用功能

九   代碼注釋
     (1)前綴注釋
        * 文件/類名
        * 最后一次修改時間
        * 原作者
        * 文件所實現特性的編號 (特性 ID)
        * 版權信息
        * 文件/類的簡要描述
        * 未完成的特性
        * 已知的 bug

     (2)注釋示例
        /*
         * Watermelon.cpp
         *
         * $Id: Watermelon.cpp,v 1.6 2004/03/10 12:52:33 klep Exp $
         *
         * Implements the basic functionality of a watermelon. All
         * unit are expressed in terms of seeds per cubic centimeter
         * Watermelon theory is based on the white paper "Alogorthms
         * for Watermelon Processing."
         *
         * The following code is (c)copyright 2004. FruitSoft, Inc.
         * All right reserved
         */

十   編寫代碼
     1.類定義在 C++ 中是一條語句,因此必須以分號結束。
     2.:: 指作用域解析操作符。
     3.在棧和堆上使用對象的區別
       (1)在棧上創建對象
          SpreadsheetCell myCell, anotherCell;

       (2)在堆上使用對象
          SpreadsheetCell *myCellp = new SpreadsheetCell();

       (3)如果用 new 來分配一個對象,用完該對象時要用 delete 來釋放

     4.C++ 程序員通常把構造函數稱為 "ctor"

     5.使用構造函數
       (1)在棧上使用構造函數
          SpreadsheetCell myCell(5);

       (2)在堆上使用構造函數
          SpreadsheetCell *myCell = new SpreadsheetCell(5);
          delete myCell;

       (3)不要嘗試從類的一個構造函數調用另一個構造函數

     6.使用默認構造函數
       (1)在棧上使用構造函數
          SpreadsheetCell myCell;  //right
          SpreadsheetCell myCell();//wrong

       (2)在棧上創建對象時,要去掉默認構造函數的小括號
       (3)在堆上使用默認構造函數
          SpreadsheetCell *myCellp = new SpreadsheetCell();

       (4)什么時候需要使用構造函數
          SpreadsheetCell cells[3];//fails comilation without default ctor
         SpreadsheetCell *myCellp = new SpreadsheetCell[10];//alse fails

       (5)使用初始化列表
          1)初始化列表允許在創建數據成員的同時完成數據成員的初始化
          2)使用初始化列表的情況

      數據成員                                         解釋
      ------------------------------------------------------------------
      const 數據成員                              必須在創建時提供值
      引用數據成員                               引用無法獨立存在
      沒默認構造函數的對象成員       對象成員無法初始化
      沒有默認構造函數的超類           見后面 
      ------------------------------------------------------------------

     7.對象的撤銷
       (1)析構函數僅用于釋放內存或釋放其他資源是一個不錯的想法

     8.淺復制與深復制
       (1)淺復制:只是從源對象直接將數據成員復制或賦值到目標對象
       (2)深復制:非淺復制
       (3)只要在類中動態分配了內存,就應該編寫自己的復制構造函數來提供內存的深復制
       (4)在對一個對象進行賦值前,必須先釋放此對象的所有動態分配的內存
       (5)只要類會動態分配內存,就需要編寫析構函數、復制構造函數、賦值操作符
       (6)禁止對象賦值,可將復制構造函數與賦值操作符聲明為私有成員
       (7)不必為私有復制構造函數和賦值操作符提供實現,編譯器不要求

十一 精通類和對象
     1.不能在靜態方法中訪問非靜態數據成員
     2.保證一個對象不會修改數據成員,可用 const 來標記

     3.保證一個方法不會修改數據成員,可用 const 來標記
       (1)在類定義中的聲明 double getValue() const;
       (2)在源文件中的實現
          double Spreadsheet::getValue() const
         {
            return this.mValue;
         }

     4.非 const 對象可以調用 const 和非 const 方法,const 對象只能調用const 方法

     5.應將所有不會修改對象的方法都聲明為 const,并在程序中使用 const對象引用

     6.將變量置為 mutable,這樣編譯器允許在 const 方法中修改這個變量
     7.C++ 不允許僅基于方法的返回類型而重載一個方法名
     8.默認參數:從最右參數開始的連續參數表
     9.只能在方法聲明中指定默認參數,在定義中并不指定
     10一個構造函數的所有參數都有默認值,此函數會作為默認構造函數
     11能利用默認參數做到的事情,利用方法重載也可以做,用你最熟悉的

     12內聯:將方法體或函數體直接插入到代碼調用處(相當于 #define 宏的安
       全版本),內聯示例如下:

       (1)在類的源文件(SpreadsheetCell.cpp)
       inline double SpreadsheetCell::getValue() const
       {
           mNumAccess++;
           return mValue;
       }

       (2)或在類的聲明文件中直接實現此方法而不用 inline 關鍵字
       //SpreadsheetCell.h
       double getValue() const (mNumAccesses++; return mValue;}

     13友元可以訪問指定類中的 protected 和 private 數據成員和方法
       (1)聲明友元類
          class SpreadsheetCell
          {
             public:
                 friend class Spreadsheet;
                //code omitted here
          };

       (2)聲明友元方法
          class SpreadsheetCell
         {
             public:
                 friend bool checkSpreadsheetCell();
                 //code omitted here
         };


十二 C++ 中的繼承機制
     1.超類指針(引用)在引用子類時,了類仍然會保留它們覆蓋的方法。而在
       強制類型轉換成超類對象時,子類會失去它們的獨有特性。覆蓋方法和子
       類數據的丟失稱為切割。

     2.作為一條經驗,要把所有的方法都用 virtual 聲明 (包括析構函數,但
       是不包括構造函數) 來避免因遺漏關鍵字 virtual 而產生的相關問題。

     3.virtual 用法示例:
       class Sub : public Super
       {
           public:
           Sub();
           virtual void someMethod();
           virtual void someOtherMethod();
       }

     4.要把所有的析構函數都用 virtual 聲明

     5.強制類型轉換
       (1)靜態轉換 static_cast<type>
          示例:
          Sub* mySub = static_cast<Sub*>(inSuper);

       (2)動態轉換 dynamic_cast<type>
          示例:
          Sub* mySub = dynamic_cast<Sub*>(inSuper);
          if (mySub == NULL)
         {
              //proceed to access sub methods on mySub
         }
  
   注意:如果對指針不能進行動態類型轉換,指針則為 NULL, 而不是指
   向無意義的數據。

     6.進行向上強制類型轉換時,要使用指向超類的指針或引用來避免切割問題。

     7.純虛方法與抽象基類
       (1)純虛方法: 在類定義中顯示未定義的方法。
       (2)抽象類: 含有純虛方法的類(不能實例化)。
       (3)純虛方法語法定義: 在類定義中簡單的設置方法等于 0,在 cpp 文件
          中不要編寫其實現代碼。
   示例:
   class SpreadsheetCell
   {
       public:
           SpreadsheetCell();
           virtual ~SpreadsheetCell();
           virtual void set(const std::string instring) = 0;
           virtual std::string getString() const = 0;
     };

     8.定制類型轉換函數
       (1)double 類型轉換成 string 類型
          #include <iostream>
          #include <sstream>
  
          double inValue;
          string myString;

          ostringstream ostr;
          ostr << inValue;
          myString = ostr.str();

       (2)string 類型轉換成 double 類型
          #include <iostream>
          #include <sstream>
  
          double myDouble;
          string inString;
  
          istringStream istr(inString);
          istr >> myDouble;
         if (istr.fail())
        {
           myDouble = 0;
        }

     9.使用預編譯指令避免重復包含頭文件
       #ifndef _TEST_H_
       #define _TEST_H_
       // include header files here      
       // other code omitted here

       #endif
  
十三 覆蓋方法的特殊情況
     1.在 C++ 中不能覆蓋靜態方法。
       (1)不能同時用 virtual 和 static 聲明一個方法。
       (2)在對象上可以調用 static 方法,但 static 方法只存在于類中。

十四 利用模板編寫通用代碼
     1.模板相關概念
       (1)類模板: 存儲對象的容器或數據結構。
       (2)模板的語法:
          template <typename T>
         class Grid
         {
             public:
                 Grid(int inWidth, int inHeight);
                 Grid(const Grid<T>& src);
                 Grid<T>& operator=(const Grid<T>& rhs);
                 T& getElementAt(int x, int y);
                 const T& getElementAt(int x, int y);
                 void setElementAt(int x, int y, const T& inElem);

             protected:
                 void copyFrom(const Grid<T>& src);
                 T** mCells;
        };
        (3)語法解釋
            template <typename T> : 指在類型 T 上定義的模板。
            Grid<T> : Grid 實際上是模板名。
            Grid<T> : 將作為類模板中的類名。

 (4)模板定義(實現)
    template <typename T>
    Grid<T>::Grid(int inWidth, int inHeight)
    {
        mCells = new T* [mWidth];
        for (int i = 0; i < mWidth; i++)
        {
            mCells[i] = new T[mHeight];
        }
    }

 (5)模板實例化
    Grid<int> myIntGrid;

十五 C++ 中的一些疑難問題
     1.引用
       (1)定義: 另一個變量的別名, 對引用的修改會改變其所指向的變量。
       (2)引用變量必須在創建時就初始化。
          int  x = 3;   // right
          int& xRef = x;// right
          int& emptyRef;//wrong
          注: 類的引用數據成員可在構造函數的初始化列表中初始化。

       (3)不能創建指向未命名值的引用(const 常量值除外)
          int& unnameRef = 5;      //does not compile
          const int& unnameRef = 5;//works as expect

       (4)修改引用: 引用總是指向初始化時指定的那個變量。
          int x = 3, y = 4;
          int& xRef = x;
          xRef = y; // change x value to 4, doesn't make refer to y;
          xRef = &y; // doesn't compile, type not match
         注: 引用指向的變量在初始化之后不能再改變, 只能改變此變量的值

       (5)指針引用和引用指針
          //指針引用示例(指向指針的引用)
          int*  intP;
          int*& ptrRef = intP;
          ptrRef = new int;
         *ptrRef = 5;

         注:不能聲明指向引用的引用, 也不能聲明引用指針(指向引用的指針)
         int x = 3;
         int& xRef = x;
         int&& xDoubleRef = xRef; // not compile
         int&* refPtr = &xRef; // not compile
  
       (6)傳引用vs傳值
          1)效率。復制大對象和結構要花費很長時間。
          2)正確性。不是所有的對象都允許傳值或正確的支持深復制。
          3)不想修改原對象,又利用以上兩優點,可在參數前加 const。
         4)對簡單內置類型(如int或double)要傳值,其它所有情況可傳引用。

       (7)引用vs指針
          1)引用讓程序清晰,易于理解。
          2)引用比指針安全,不存在無效的引用,不需要明確解除引用。
          3)除非需要動態分配內存或在其它地方要改變或釋放指針指向的值,否則都應使用引用而非指針。
    
     2.疑難字 const
       (1)const 變量
          使用 const 來聲明變量,對不能對其修改,以保護變量。

       (2)const 指針
       //不能改變指針指向的值
          const int* ip;
          ip = new int[10];
          ip[4] = 5; // not compile
        或
          int const* ip;
          ip = new int[10];
          ip[4] = 5; // not compile
 
          //不能改變指針自身
          int* const ip;
          ip = new int[10]; // not compile
          ip[4] = 5;

         //既不能改變指針也不能改變指針指向的值
         const int* const ip = NULL;(無用的指針)
          注: const 可以放在類型前也可以放在類型后
  
       (3)const 應用規則
          const 應用于其左則的第一項。

       (4)把對象參數傳遞時,默認的做法是把傳遞 const 引用。

       (5)const 方法
          用 const 標識類方法,可以防止方法修改類中不可變的數據成員。

     3.關鍵字 static
       (1)關于連接: C++ 中的每個源文件是獨立編譯的,得到的對象連接在一
          起。

       (2)外部連接: 一個源文件中每個名字(如函數或全局變量)對其它源文件
          是可用的。

       (3)內部連接: 一個源文件中每個名字(如函數或全局變量)對其它源文件
          是不可用的。內部連接也叫靜態連接。

       (4)函數和全局變量默認是外部連接。

       (5)聲明前加 static 可指定為內部連接。

     4.關鍵字 extern
       (1)作用: 與 static 相對,用來為位于它前面的名字聲明外部連接。
       (2)extern 用法
          // AnotherFile.cpp
         extern int x; // 只是聲明 x 為外部連接而不分配內存
         int x = 3;    //顯示定義以分配內存
        或
          extern int x = 3;//聲明和定義一起完成

          //FirstFile.cpp
         extern int x;
         cout << x << endl;

      5.強制類型轉換
      (1)const_cast<type> 去除變量的常量性。
      示例:
      void g(char* str)
      {
          // body omitted here
      }
      void f(const char* str)
      {
          g(const_cast<char*>(str));
          // other code omitted here
      }      

 (2)static_cast<type> 顯示的完成 C++ 語言支持的轉換。
    示例:
    int x = 3;
    double result = static_cast<double>(i) /10;

    注: static_cast 進行類型轉換時并不完成運行時類型檢查。

 (3)dynamic_cast<type>
    1)對類型強制轉換完成運行時類型檢查。
    2)對指針轉換失敗時會返回 NULL。
    3)對引用轉換失敗時會拋出 bad_cast 異常。

 
6.函數指針
        (1)定義: 把函數地址作為參數,可以像變量一樣使用。
        (2)定義函數指針: typedef bool(*YesNoFcn) (int, int);
        (3)用法示例

           //定義函數指針類型
           typedef string(*YesNoFcn)(int, int);

           void test(int value1, int values2, YesNoFcn isFunction)
          {
             cout << isFunction(value1, value2);
          }

         string intEqual(int intItem1, int intItem2)
         {
            return (intItem1 == intItem2) ? "match" : "not match";
         }

         //使用函數指針
          test(1, 1, &intEqual);

         注: & 是可選的


十六 C++ 中的 I/O 操作
     1.使用流
       (1)每個輸入流都有一個相關聯的源,每個輸出流都有一個相關聯的目的。

       (2)cout 和 cin 都是在 C++ 的 std 命名空間中預定義的流實例。

       (3)流的三種類型:
          1)控制臺輸入輸出流。
          2)文件流。
          3)字符串流。

       (4)輸出流
          1)輸出流在頭文件 <ostream> 中定義,輸入流在 <istream> 中定義<iosream> 中定義了輸入輸出流。

          2)cout 和 cin 指控制臺輸入輸出流。

          3)<< 操作符是使用輸出流的最簡單的方法。

          4)流其它的輸出方法
             1)put() 和 wirte()
             2)flush() 刷新輸出
 
          5)處理輸出錯誤
             1)cout.good()  流是否處于正常的可用狀態。
             2)cout.bad()   流輸出是否發生了錯誤。
             3)cout.fail()  如果最近的操作失敗則返回 true
             4)cout.clear() 重置流的錯誤狀態

   6)輸出控制符
     1)endl         輸出回車并刷新其緩沖區
     2)hex oct dec  以十六/八/十進制輸出
     3)setw         設置輸出數值數據時的字段占位符
     4)setfill    設置填充空位的占位符

       (5)輸入流
          1)>> 輸入流操作符
          2)輸入方法
              1)get()    僅僅返回流中的下一個字符
              2)unget()    引起流回退一個位置
              3)peek()    預覽下一個值
              4)getline()    從輸入流中取一行數據

          3)處理輸入錯誤
             1)good()
             2)eof()

       (6)字符串流
          1)<ssteam>    定義了字符串流的頭文件
         2)ostringstream  字符串輸出流
         3)istringstream  字符串輸入流

       (7)文件流
          1)<fstream>      定義了文件流的頭文件
          2)ifstream    文件輸入流
          3)ofstream    文件輸出流
          4)seek()    定位流的位置
          5)tell()    查詢流當前的位置

       (8)鏈接流
          1)定義: 在任何輸入流與輸出流之間建立連接,一旦訪問就刷新輸出。
          2)實現: 用輸入流的 tie() 方法
          3)示例
            #include <iostream>
           #inlcude <fstream>
           #include <string>

           main()
           {           
                ifstream inFile("input.txt");
               ofstream outFile("output.txt");
    
                //set up a link between inFile and outFile.
                inFile.tie(&outFile);

               string nextToken;
               inFile >> nextToken;
         }


十七 C++ 中的異常
     1.拋出和捕獲異常
       (1)<exception> 定義異常類的頭文件。
       (2)拋出異常對象 throw exception()
       (3)向量的使用(整型)
        vector<int> myInts;
        for (int i = 0; i < 10; i++)
        {
             myInts.push_back(i);// 增加元素
             cout << myInts[i];
        }

       (4)string 風格的字符串轉換成 C 風格的字符串
          string myString = "string style string";
          char* cStyleStrng = myString.c_str();

       (5)捕獲運行時異常
          try
         {
            ...
          }
          catch (const runtime_error& e)
         {
           ...
         }

       (6)拋出和捕獲無效參數異常
          throw invalid_argument("");

         try
          {
            ...
          }
          catch (const invalid_argument& e)
          {
             ...
          }

         注: runtime_error 和 invalid_argument 定義在頭文件<stdexcept> 中

       (7)匹配任何異常(...)
          try
          {
            // code omitted here
          }
          catch (...)
          {
            // code omitted
          }
         注: 不建議使用這種方式

       (8)使用拋出列表
          1)拋出列表: 一個函數或方法能拋出的異常列表
          2)必須為函數聲明和實現都提供拋出列表
          3)沒有拋出列表就可以拋出任何異常
         4)空的拋出列表不允許拋出任何異常

       (9)在覆蓋方法中修改參數列表
          1)從列表中刪除異常
          2)增加超類拋出列表中異常的子類
          3)不能完全刪除拋出列表

       (10)顯示異常消息
           可調用 exception 或子類的 what() 方法顯示捕獲到的異常消息
           示例:
           try
           {
               ...
           }
           catch (const exception& e)
           {
               cerr << e.what() << endl;
               exit(1);
           }
            
       (11)多態地捕獲異常
           1)在多態地捕獲異常時,要確保按引用捕獲異常。如果按值捕獲異常,就會遇到切割問題,丟失對象的信息。

           2)按引用捕獲異??梢员苊獠槐匾膹椭崎_銷

       (12)如果異常處理不夠仔細,就會導致內存和資源泄漏
           示例
           func ()
          {
            string str1;
            string* str2 = new string();
            throw exception();
            delete str2;     // 內存泄漏
          }

       (13)使用智能指針防止內存泄漏
           #include <memory> // 定義智能指針的頭文件
           using namespace std;
           func ()
           {
               string str1;

               // 智能指針,不用自己手動釋放
              auto_ptr<string> str2(new string("hello"));
              throw exception();
           }

       (14)處理內存分配錯誤
           1)new 和 new [] 分配內存失敗默認拋出 bad_alloc 異常
           2)可用 try/catch 捕獲異常處理內存分配失敗
           3)示例:
             try
             {
                 ptr = new int[numInts];
             }
             catch (bad_alloc& e)
            {
              cerr << "Unable to alloc memory!" << endl;
              return ;
            }
         或
          1)用 new(nothrow) 在內存分配失敗時返回 NULL 來處理
          2)示例:
             ptr = new(nothrow) int[numInts];
            if (ptr == NULL)
            {
               cerr << "Unable to alloc memory!" << endl;
               return;
            }
         或
           1)用 set_new_handler() 回調函數定制分配失敗時的行為
           2)示例
              void myNewHandler()
             {
                cerr << "Unable to allocate memory!" << endl;
                abort(); // 終止程序 <cstdlib>
             }
            
             #include <new>
            #include <cstdlib>
            #include <iostream>
            using namespace std;
     
            int main(int argc, char** argv)
           {
               new_handler oldHandler = set_new_handler(myNewHandler);

              // code omitted here

             set_new_handler(oldHandler);
             return (0);
         }

posted on 2007-08-20 16:15 Normandy 閱讀(970) 評論(1)  編輯 收藏 引用 所屬分類: Programming

評論

# re: C++ 學習筆記  回復  更多評論   

做的 professional C++這本書上的筆記吧!很好.....
2008-01-21 15:16 | LJL
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久久久久一区二区| 一区二区亚洲精品| 亚洲视频在线免费观看| 亚洲韩国日本中文字幕| 久久漫画官网| 久久久欧美精品sm网站| 久久久久成人精品免费播放动漫| 欧美一区二区三区在线观看| 欧美一区国产二区| 久久一区免费| 亚洲私人影院在线观看| 午夜精品国产更新| 黄色日韩精品| 午夜精彩视频在线观看不卡 | 亚洲日本中文字幕免费在线不卡| 亚洲黄色毛片| 亚洲视频www| 久久精品理论片| 麻豆freexxxx性91精品| 欧美高清在线播放| 国产精品久久久久免费a∨ | 国产综合色产| 亚洲激情中文1区| 亚洲综合精品自拍| 久久尤物视频| 亚洲乱亚洲高清| 久久久久久久综合狠狠综合| 欧美精品成人| 国产在线视频欧美一区二区三区| 亚洲欧洲精品一区二区| 欧美在线一级视频| 亚洲精品乱码久久久久久黑人 | 亚洲视频综合| 久久综合九色综合久99| 亚洲三级视频| 久久久精品tv| 国产精品亚洲产品| 亚洲国产欧洲综合997久久| 亚洲少妇自拍| 欧美激情亚洲国产| 欧美在线啊v一区| 国产精品v片在线观看不卡| 亚洲国产精品福利| 久久精品首页| 亚洲素人一区二区| 欧美精品少妇一区二区三区| 红桃视频国产一区| 午夜国产一区| 中日韩午夜理伦电影免费| 米奇777超碰欧美日韩亚洲| 国产日韩一区二区三区| 亚洲午夜在线观看视频在线| 欧美激情在线观看| 亚洲国产高清在线| 久久久精品五月天| 国产视频一区二区三区在线观看| 在线一区二区三区做爰视频网站 | 亚洲最新合集| 在线免费观看一区二区三区| 欧美一级精品大片| 99ri日韩精品视频| 欧美久久久久久久久久| 亚洲电影免费观看高清完整版在线观看 | 欧美激情精品久久久久久黑人| 小辣椒精品导航| 国产欧美一区二区三区视频| 午夜精品久久久久久久久| 日韩视频在线观看| 亚洲欧美激情诱惑| 国产精品亚洲欧美| 欧美在线二区| 久久xxxx精品视频| 国模精品一区二区三区色天香| 欧美一区在线视频| 午夜久久福利| 在线观看欧美黄色| 亚洲精品视频在线看| 欧美日韩精品一区二区三区| 亚洲欧美激情诱惑| 久久gogo国模裸体人体| 亚洲国产电影| 99国产一区| 国产一区二区三区久久久久久久久| 久久午夜国产精品| 欧美精品一区二区久久婷婷| 亚洲在线成人精品| 久久精品国产一区二区电影| 日韩视频永久免费观看| 亚洲在线免费视频| 亚洲国产精品久久久久秋霞蜜臀 | 欧美成人乱码一区二区三区| 亚洲小少妇裸体bbw| 欧美综合77777色婷婷| 亚洲欧洲日韩综合二区| 中文无字幕一区二区三区| 韩日视频一区| 99国产麻豆精品| 伊人精品在线| 一区二区三区导航| 亚洲福利电影| 这里只有精品电影| 激情av一区二区| 艳妇臀荡乳欲伦亚洲一区| 国产精品午夜av在线| 亚洲国产日韩欧美一区二区三区| 欧美精品www| 欧美一区二区三区在线视频| 亚洲国产欧美在线| 精品51国产黑色丝袜高跟鞋| 欧美亚男人的天堂| 国产精品毛片大码女人| 久久精品国产77777蜜臀| 久久久久久一区| 激情懂色av一区av二区av| 亚洲国内欧美| 国产一区二区黄| 日韩视频一区二区三区在线播放免费观看 | 一区二区三区四区五区视频 | 亚洲日本va午夜在线电影| 国产伦精品一区二区三区高清版| 美国十次成人| 国产精品www994| 午夜精品一区二区三区电影天堂| 欧美精品成人91久久久久久久| 亚洲欧美视频| 欧美精品九九| 免费观看成人| 国产欧美在线观看一区| 狂野欧美激情性xxxx欧美| 欧美日韩一区在线观看视频| 噜噜噜噜噜久久久久久91| 国产精品a久久久久| 欧美黄色免费网站| 国产一区二区三区四区五区美女 | 久久超碰97人人做人人爱| 国产精品国产自产拍高清av王其 | 亚洲欧美日本精品| 一区二区免费在线观看| 久久久精品欧美丰满| 性欧美8khd高清极品| 欧美日韩精品在线观看| 久久本道综合色狠狠五月| 国产视频一区欧美| 亚洲一区二区在| 亚洲一区二区在线| 欧美精品v日韩精品v韩国精品v| 裸体歌舞表演一区二区| 国产亚洲观看| 久久久久国产一区二区三区四区| 欧美在线关看| 国产欧美视频一区二区| 亚洲视频精选| 亚洲一区二区三区免费视频| 欧美欧美天天天天操| 亚洲视频免费观看| 亚洲一区二区三区在线观看视频 | 一区二区三区久久| 欧美黑人国产人伦爽爽爽| 欧美寡妇偷汉性猛交| 韩国成人福利片在线播放| 亚洲一区二区三区精品动漫| 久久精品国产一区二区三| 国产日韩欧美一区在线| 欧美一级视频精品观看| 久久精品一区| 精品动漫3d一区二区三区免费版| 艳女tv在线观看国产一区| 久久国产精品久久久| 国产亚洲欧美日韩日本| 欧美在线亚洲一区| 麻豆精品视频在线观看视频| …久久精品99久久香蕉国产| 亚洲一区二区三区精品动漫| 蜜臀99久久精品久久久久久软件 | 免费日韩精品中文字幕视频在线| 久久影院午夜片一区| 亚洲黄色免费| 欧美日韩国产综合一区二区| 亚洲高清视频的网址| 性做久久久久久| 一区在线影院| 欧美精品自拍| 亚洲欧美色婷婷| 麻豆精品网站| 极品少妇一区二区三区| 国产精品久久久久高潮| 久久久国产亚洲精品| 亚洲精品综合精品自拍| 欧美伊人久久久久久久久影院| 精品动漫一区二区| 国产日韩欧美成人| 免费亚洲电影在线观看| 亚洲新中文字幕| 欧美激情a∨在线视频播放| 亚洲一级电影| 国产精品久久久亚洲一区| 欧美国产亚洲精品久久久8v| 亚洲小说欧美另类社区| 欧美高清视频在线| 香港久久久电影|