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

專職C++

不能停止的腳步

  C++博客 :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
  163 Posts :: 7 Stories :: 135 Comments :: 0 Trackbacks

常用鏈接

留言簿(28)

我參與的團(tuán)隊(duì)

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

轉(zhuǎn)貼說(shuō)明:前幾天,去某公司面試。被問(wèn)到多態(tài)。汗,我居然沒(méi)有答上來(lái)。
我不是不懂多態(tài),只是用多了,而忘了對(duì)應(yīng)的名詞了。模板寫(xiě)多了,我的程序中,大多是模板,成習(xí)慣了。也就是靜態(tài)多態(tài)。
除此之后,我還把網(wǎng)上的MD5,CRC32,Base64等,全改成模板了。(具體看我的開(kāi)源庫(kù))。
這里我轉(zhuǎn)貼了一個(gè)C++多態(tài)文章,如果你也忘了,就當(dāng)復(fù)習(xí)一下吧。

轉(zhuǎn)貼頁(yè)的地址:http://www.vckbase.com/document/viewdoc/?id=948

作者:榮耀

提交者:eastvc 發(fā)布日期:2003-12-14 19:38:12
原文出處:http://www.royaloo.com/articles/articles_2003/PolymorphismInCpp_content.htm


摘要

本文描述了C++中的各種多態(tài)性。重點(diǎn)闡述了面向?qū)ο蟮膭?dòng)態(tài)多態(tài)和基于模板的靜態(tài)多態(tài),并初步探討了兩種技術(shù)的結(jié)合使用。 

關(guān)鍵詞

多態(tài)  繼承  虛函數(shù)  模板  宏  函數(shù)重載 泛型編程  泛型模式  

導(dǎo)言

多態(tài)(polymorphism)一詞最初來(lái)源于希臘語(yǔ)polumorphos,含義是具有多種形式或形態(tài)的情形。在程序設(shè)計(jì)領(lǐng)域,一個(gè)廣泛認(rèn)可的定義是“一種將不同的特殊行為和單個(gè)泛化記號(hào)相關(guān)聯(lián)的能力”。和純粹的面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言不同,C++中的多態(tài)有著更廣泛的含義。除了常見(jiàn)的通過(guò)類繼承和虛函數(shù)機(jī)制生效于運(yùn)行期的動(dòng)態(tài)多態(tài)(dynamic polymorphism)外,模板也允許將不同的特殊行為和單個(gè)泛化記號(hào)相關(guān)聯(lián),由于這種關(guān)聯(lián)處理于編譯期而非運(yùn)行期,因此被稱為靜態(tài)多態(tài)(static polymorphism)。 
事實(shí)上,帶變量的宏和函數(shù)重載機(jī)制也允許將不同的特殊行為和單個(gè)泛化記號(hào)相關(guān)聯(lián)。然而,習(xí)慣上我們并不將它們展現(xiàn)出來(lái)的行為稱為多態(tài)(或靜態(tài)多態(tài))。今天,當(dāng)我們談及多態(tài)時(shí),如果沒(méi)有明確所指,默認(rèn)就是動(dòng)態(tài)多態(tài),而靜態(tài)多態(tài)則是指基于模板的多態(tài)。不過(guò),在這篇以C++各種多態(tài)技術(shù)為主題的文章中,我們首先還是回顧一下C++社群爭(zhēng)論已久的另一種“多態(tài)”:函數(shù)多態(tài)(function polymorphism),以及更不常提的“宏多態(tài)(macro polymorphism)”。 

函數(shù)多態(tài)

也就是我們常說(shuō)的函數(shù)重載(function overloading)。基于不同的參數(shù)列表,同一個(gè)函數(shù)名字可以指向不同的函數(shù)定義: 

// overload_poly.cpp

#include <iostream>
#include <string>

// 定義兩個(gè)重載函數(shù)

int my_add(int a, int b)
{
    return a + b;
}

int my_add(int a, std::string b)
{
    return a + atoi(b.c_str());
}

int main()
{
    int i = my_add(1, 2);                // 兩個(gè)整數(shù)相加
    int s = my_add(1, "2");              // 一個(gè)整數(shù)和一個(gè)字符串相加
    std::cout << "i = " << i << "\n";
    std::cout << "s = " << s << "\n";


根據(jù)參數(shù)列表的不同(類型、個(gè)數(shù)或兼而有之),my_add(1, 2)和my_add(1, "2")被分別編譯為對(duì)my_add(int, int)和my_add(int, std::string)的調(diào)用。實(shí)現(xiàn)原理在于編譯器根據(jù)不同的參數(shù)列表對(duì)同名函數(shù)進(jìn)行名字重整,而后這些同名函數(shù)就變成了彼此不同的函數(shù)。比方說(shuō),也許某個(gè)編譯器會(huì)將my_add()函數(shù)名字分別重整為my_add_int_int()和my_add_int_str()。 

宏多態(tài)

帶變量的宏可以實(shí)現(xiàn)一種初級(jí)形式的靜態(tài)多態(tài): 
// macro_poly.cpp

#include <iostream>
#include <string>

// 定義泛化記號(hào):宏ADD
#define ADD(A, B) (A) + (B);

int main()
{
    int i1(1), i2(2);
    std::string s1("Hello, "), s2("world!");
    int i = ADD(i1, i2);                        // 兩個(gè)整數(shù)相加
    std::string s = ADD(s1, s2);                // 兩個(gè)字符串“相加”
    std::cout << "i = " << i << "\n";
    std::cout << "s = " << s << "\n";
}
當(dāng)程序被編譯時(shí),表達(dá)式ADD(i1, i2)和ADD(s1, s2)分別被替換為兩個(gè)整數(shù)相加和兩個(gè)字符串相加的具體表達(dá)式。整數(shù)相加體現(xiàn)為求和,而字符串相加則體現(xiàn)為連接。程序的輸出結(jié)果符合直覺(jué): 
1 + 2 = 3
Hello, + world! = Hello, world!

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

這就是眾所周知的的多態(tài)。現(xiàn)代面向?qū)ο笳Z(yǔ)言對(duì)這個(gè)概念的定義是一致的。其技術(shù)基礎(chǔ)在于繼承機(jī)制和虛函數(shù)。例如,我們可以定義一個(gè)抽象基類Vehicle和兩個(gè)派生于Vehicle的具體類Car和Airplane: 

// dynamic_poly.h

#include <iostream>

// 公共抽象基類Vehicle
class Vehicle
{
public:
    virtual void run() const = 0;
};

// 派生于Vehicle的具體類Car
class Car: public Vehicle
{
public:
    virtual void run() const
    {
        std::cout << "run a car\n";
    }
};

// 派生于Vehicle的具體類Airplane
class Airplane: public Vehicle
{
public:
    virtual void run() const
    {
        std::cout << "run a airplane\n";
    }
}; 
客戶程序可以通過(guò)指向基類Vehicle的指針(或引用)來(lái)操縱具體對(duì)象。通過(guò)指向基類對(duì)象的指針(或引用)來(lái)調(diào)用一個(gè)虛函數(shù),會(huì)導(dǎo)致對(duì)被指向的具體對(duì)象之相應(yīng)成員的調(diào)用:

// dynamic_poly_1.cpp

#include <iostream>
#include <vector>
#include "dynamic_poly.h"

// 通過(guò)指針run任何vehicle
void run_vehicle(const Vehicle* vehicle)
{
    vehicle->run();            // 根據(jù)vehicle的具體類型調(diào)用對(duì)應(yīng)的run()
}

int main()
{
    Car car;
    Airplane airplane;
    run_vehicle(&car);         // 調(diào)用Car::run()
    run_vehicle(&airplane);    // 調(diào)用Airplane::run()
}

此例中,關(guān)鍵的多態(tài)接口元素為虛函數(shù)run()。由于run_vehicle()的參數(shù)為指向基類Vehicle的指針,因而無(wú)法在編譯期決定使用哪一個(gè)版本的run()。在運(yùn)行期,為了分派函數(shù)調(diào)用,虛函數(shù)被調(diào)用的那個(gè)對(duì)象的完整動(dòng)態(tài)類型將被訪問(wèn)。這樣一來(lái),對(duì)一個(gè)Car對(duì)象調(diào)用run_vehicle(),實(shí)際上將調(diào)用Car::run(),而對(duì)于Airplane對(duì)象而言將調(diào)用Airplane::run()。
或許動(dòng)態(tài)多態(tài)最吸引人之處在于處理異質(zhì)對(duì)象集合的能力: 

// dynamic_poly_2.cpp

#include <iostream>
#include <vector>
#include "dynamic_poly.h"

// run異質(zhì)vehicles集合
void run_vehicles(const std::vector<Vehicle*>& vehicles)
{
    for (unsigned int i = 0; i < vehicles.size(); ++i)
    {
        vehicles[i]->run();     // 根據(jù)具體vehicle的類型調(diào)用對(duì)應(yīng)的run()
    }
}

int main()
{
    Car car;
    Airplane airplane;
    std::vector<Vehicle*> v;    // 異質(zhì)vehicles集合
    v.push_back(&car);
    v.push_back(&airplane);
    run_vehicles(v);            // run不同類型的vehicles
}
在run_vehicles()中,vehicles[i]->run()依據(jù)正被迭代的元素的類型而調(diào)用不同的成員函數(shù)。這從一個(gè)側(cè)面體現(xiàn)了面向?qū)ο缶幊田L(fēng)格的優(yōu)雅。

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

如果說(shuō)動(dòng)態(tài)多態(tài)是通過(guò)虛函數(shù)來(lái)表達(dá)共同接口的話,那么靜態(tài)多態(tài)則是通過(guò)“彼此單獨(dú)定義但支持共同操作的具體類”來(lái)表達(dá)共同性,換句話說(shuō),必須存在必需的同名成員函數(shù)。 
我們可以采用靜態(tài)多態(tài)機(jī)制重寫(xiě)上一節(jié)的例子。這一次,我們不再定義vehicles類層次結(jié)構(gòu),相反,我們編寫(xiě)彼此無(wú)關(guān)的具體類Car和Airplane(它們都有一個(gè)run()成員函數(shù)): 

// static_poly.h

#include <iostream>

//具體類Car
class Car
{
public:
    void run() const
    {
        std::cout << "run a car\n";
    }
};

//具體類Airplane
class Airplane
{
public:
    void run() const
    {
        std::cout << "run a airplane\n";
    }
};

run_vehicle()應(yīng)用程序被改寫(xiě)如下:
 
// static_poly_1.cpp

#include <iostream>
#include <vector>
#include "static_poly.h"

// 通過(guò)引用而run任何vehicle
template <typename Vehicle>
void run_vehicle(const Vehicle& vehicle)
{
    vehicle.run();            // 根據(jù)vehicle的具體類型調(diào)用對(duì)應(yīng)的run()
}
 
int main()
{
    Car car;
    Airplane airplane;
    run_vehicle(car);         // 調(diào)用Car::run()
    run_vehicle(airplane);    // 調(diào)用Airplane::run()

現(xiàn)在Vehicle用作模板參數(shù)而非公共基類對(duì)象(事實(shí)上,這里的Vehicle只是一個(gè)符合直覺(jué)的記號(hào)而已,此外別無(wú)它意)。經(jīng)過(guò)編譯器處理后,我們最終會(huì)得到run_vehicle<Car>()和 run_vehicle<Airplane>()兩個(gè)不同的函數(shù)。這和動(dòng)態(tài)多態(tài)不同,動(dòng)態(tài)多態(tài)憑借虛函數(shù)分派機(jī)制在運(yùn)行期只有一個(gè)run_vehicle()函數(shù)。 
我們無(wú)法再透明地處理異質(zhì)對(duì)象集合了,因?yàn)樗蓄愋投急仨氃诰幾g期予以決定。不過(guò),為不同的vehicles引入不同的集合只是舉手之勞。由于無(wú)需再將集合元素局限于指針或引用,我們現(xiàn)在可以從執(zhí)行性能和類型安全兩方面獲得好處: 

// static_poly_2.cpp

#include <iostream>
#include <vector>
#include "static_poly.h"

// run同質(zhì)vehicles集合
template <typename Vehicle>
void run_vehicles(const std::vector<Vehicle>& vehicles)
{
    for (unsigned int i = 0; i < vehicles.size(); ++i) 
    {
        vehicles[i].run();            // 根據(jù)vehicle的具體類型調(diào)用相應(yīng)的run()
    }
}

int main()
{
    Car car1, car2;
    Airplane airplane1, airplane2;

    std::vector<Car> vc;              // 同質(zhì)cars集合
    vc.push_back(car1);
    vc.push_back(car2);
    //vc.push_back(airplane1);        // 錯(cuò)誤:類型不匹配
    run_vehicles(vc);                 // run cars

    std::vector<Airplane> vs;         // 同質(zhì)airplanes集合
    vs.push_back(airplane1);
    vs.push_back(airplane2);
    //vs.push_back(car1);             // 錯(cuò)誤:類型不匹配
    run_vehicles(vs);                 // run airplanes
}

兩種多態(tài)機(jī)制的結(jié)合使用 

在一些高級(jí)C++應(yīng)用中,我們可能需要結(jié)合使用動(dòng)態(tài)多態(tài)和靜態(tài)多態(tài)兩種機(jī)制,以期達(dá)到對(duì)象操作的優(yōu)雅、安全和高效。例如,我們既希望一致而優(yōu)雅地處理vehicles的run問(wèn)題,又希望“安全而高效”地完成給飛行器(飛機(jī)、飛艇等)進(jìn)行“空中加油”這樣的高難度動(dòng)作。為此,我們首先將上面的vehicles類層次結(jié)構(gòu)改寫(xiě)如下: 

// dscombine_poly.h

#include <iostream>
#include <vector>

// 公共抽象基類Vehicle
class Vehicle
{
    public:
    virtual void run() const = 0;
};

// 派生于Vehicle的具體類Car
class Car: public Vehicle
{
public:
    virtual void run() const
    {
        std::cout << "run a car\n";
    }
};

// 派生于Vehicle的具體類Airplane
class Airplane: public Vehicle
{
public:
    virtual void run() const
    {
        std::cout << "run a airplane\n";
    }
 
    void add_oil() const
    {
        std::cout << "add oil to airplane\n";
    }
};

// 派生于Vehicle的具體類Airship
class Airship: public Vehicle
{
public:
    virtual void run() const
    {
        std::cout << "run a airship\n";
    }
  
    void add_oil() const
    {
        std::cout << "add oil to airship\n";
    }
};

我們理想中的應(yīng)用程序可以編寫(xiě)如下:
 
// dscombine_poly.cpp

#include <iostream>
#include <vector>
#include "dscombine_poly.h"

// run異質(zhì)vehicles集合
void run_vehicles(const std::vector<Vehicle*>& vehicles)
{
    for (unsigned int i = 0; i < vehicles.size(); ++i)
    {
        vehicles[i]->run();                 // 根據(jù)具體的vehicle類型調(diào)用對(duì)應(yīng)的run()
    }
}

// 為某種特定的aircrafts同質(zhì)對(duì)象集合進(jìn)行“空中加油”
template <typename Aircraft>
void add_oil_to_aircrafts_in_the_sky(const std::vector<Aircraft>& aircrafts)
{
    for (unsigned int i = 0; i < aircrafts.size(); ++i)
    {
        aircrafts[i].add_oil();
    }
}

int main()
{
    Car car1, car2;
    Airplane airplane1, airplane2;

    Airship airship1, airship2;
    std::vector<Vehicle*> v;                // 異質(zhì)vehicles集合
    v.push_back(&car1);
    v.push_back(&airplane1);
    v.push_back(&airship1);
    run_vehicles(v);                        // run不同種類的vehicles

    std::vector<Airplane> vp;               // 同質(zhì)airplanes集合
    vp.push_back(airplane1);
    vp.push_back(airplane2);
    add_oil_to_aircrafts_in_the_sky(vp);    // 為airplanes進(jìn)行“空中加油”

    std::vector<Airship> vs;                // 同質(zhì)airships集合
    vs.push_back(airship1);
    vs.push_back(airship2);
    add_oil_to_aircrafts_in_the_sky(vs);    // 為airships進(jìn)行“空中加油”


我們保留了類層次結(jié)構(gòu),目的是為了能夠利用run_vehicles()一致而優(yōu)雅地處理異質(zhì)對(duì)象集合vehicles的run問(wèn)題。同時(shí),利用函數(shù)模板add_oil_to_aircrafts_in_the_sky<Aircraft>(),我們?nèi)匀豢梢蕴幚硖囟ǚN類的vehicles — aircrafts(包括airplanes和airships)的“空中加油”問(wèn)題。其中,我們避開(kāi)使用指針,從而在執(zhí)行性能和類型安全兩方面達(dá)到了預(yù)期目標(biāo)。
 
結(jié)語(yǔ) 

長(zhǎng)期以來(lái),C++社群對(duì)于多態(tài)的內(nèi)涵和外延一直爭(zhēng)論不休。在comp.object這樣的網(wǎng)絡(luò)論壇上,此類話題爭(zhēng)論至今仍隨處可見(jiàn)。曾經(jīng)有人將動(dòng)態(tài)多態(tài)(dynamic polymorphism)稱為inclusion polymorphism,而將靜態(tài)多態(tài)(static polymorphism)稱為parametric polymorphism或parameterized polymorphism。 

我注意到2003年斯坦福大學(xué)公開(kāi)的一份C++ and Object-Oriented Programming教案中明確提到了函數(shù)多態(tài)概念:Function overloading is also referred to as function polymorphism as it involves one function having many forms。文后的“參考文獻(xiàn)”單元給出了這個(gè)網(wǎng)頁(yè)鏈接。
 
可能你是第一次看到宏多態(tài)(macro polymorphism)這個(gè)術(shù)語(yǔ)。不必訝異 — 也許我就是造出這個(gè)術(shù)語(yǔ)的“第一人”。顯然,帶變量的宏(或類似于函數(shù)的宏或偽函數(shù)宏)的替換機(jī)制除了免除小型函數(shù)的調(diào)用開(kāi)銷之外,也表現(xiàn)出了類似的多態(tài)性。在我們上面的例子中,字符串相加所表現(xiàn)出來(lái)的符合直覺(jué)的連接操作,事實(shí)上是由底部運(yùn)算符重載機(jī)制(operator overloading)支持的。值得指出的是,C++社群中有人將運(yùn)算符重載所表現(xiàn)出來(lái)的多態(tài)稱為ad hoc polymorphism。 

David Vandevoorde和Nicolai M. Josuttis在他們的著作C++ Templates: The Complete Guide一書(shū)中系統(tǒng)地闡述了靜態(tài)多態(tài)和動(dòng)態(tài)多態(tài)技術(shù)。因?yàn)檎J(rèn)為“和其他語(yǔ)言機(jī)制關(guān)系不大”,這本書(shū)沒(méi)有提及“宏多態(tài)”(以及“函數(shù)多態(tài)”)。(需要說(shuō)明的是,筆者本人是這本書(shū)的繁體中文版譯者之一,本文正是基于這本書(shū)的第14章The Polymorphic Power of Templates編寫(xiě)而成)

動(dòng)態(tài)多態(tài)只需要一個(gè)多態(tài)函數(shù),生成的可執(zhí)行代碼尺寸較小,靜態(tài)多態(tài)必須針對(duì)不同的類型產(chǎn)生不同的模板實(shí)體,尺寸會(huì)大一些,但生成的代碼會(huì)更快,因?yàn)闊o(wú)需通過(guò)指針進(jìn)行間接操作。靜態(tài)多態(tài)比動(dòng)態(tài)多態(tài)更加類型安全,因?yàn)槿拷壎ǘ急粰z查于編譯期。正如前面例子所示,你不可將一個(gè)錯(cuò)誤的類型的對(duì)象插入到從一個(gè)模板實(shí)例化而來(lái)的容器之中。此外,正如你已經(jīng)看到的那樣,動(dòng)態(tài)多態(tài)可以優(yōu)雅地處理異質(zhì)對(duì)象集合,而靜態(tài)多態(tài)可以用來(lái)實(shí)現(xiàn)安全、高效的同質(zhì)對(duì)象集合操作。 

靜態(tài)多態(tài)為C++帶來(lái)了泛型編程(generic programming)的概念。泛型編程可以認(rèn)為是“組件功能基于框架整體而設(shè)計(jì)”的模板編程。STL就是泛型編程的一個(gè)典范。STL是一個(gè)框架,它提供了大量的算法、容器和迭代器,全部以模板技術(shù)實(shí)現(xiàn)。從理論上講,STL的功能當(dāng)然可以使用動(dòng)態(tài)多態(tài)來(lái)實(shí)現(xiàn),不過(guò)這樣一來(lái)其性能必將大打折扣。 

靜態(tài)多態(tài)還為C++社群帶來(lái)了泛型模式(generic patterns)的概念。理論上,每一個(gè)需要通過(guò)虛函數(shù)和類繼承而支持的設(shè)計(jì)模式都可以利用基于模板的靜態(tài)多態(tài)技術(shù)(甚至可以結(jié)合使用動(dòng)態(tài)多態(tài)和靜態(tài)多態(tài)兩種技術(shù))而實(shí)現(xiàn)。正如你看到的那樣,Andrei Alexandrescu的天才作品Modern C++ Design: Generic Programming and Design Patterns Applied(Addison-Wesley)和Loki程序庫(kù)已經(jīng)走在了我們的前面。

參考文獻(xiàn)
1. David Vandevoorde, Nicolai M. Josuttis, C++ Templates: The Complete Guide, Addison Wesley, 2002.
2. Chris Neumann, CS193d (Summer 2003) C++ and Object-Oriented Programming, http://www.stanford.edu/class/cs193d/, 2003.

posted on 2010-12-05 22:29 冬瓜 閱讀(3051) 評(píng)論(3)  編輯 收藏 引用 所屬分類: 轉(zhuǎn)貼

Feedback

# re: C++多態(tài)技術(shù)[轉(zhuǎn)貼] 2010-12-06 21:20 Vanlin
冬瓜老大強(qiáng)大,呵呵..  回復(fù)  更多評(píng)論
  

# re: C++多態(tài)技術(shù)[轉(zhuǎn)貼] 2010-12-07 10:16 陳梓瀚(vczh)
模板當(dāng)成靜態(tài)多態(tài)就化神奇為腐朽了啊,得當(dāng)成模式匹配用……  回復(fù)  更多評(píng)論
  

# re: C++多態(tài)技術(shù)[轉(zhuǎn)貼] 2010-12-07 10:49 李現(xiàn)民
文章很好, 我也保留一份, 嘿嘿  回復(fù)  更多評(píng)論
  

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美激情四色| 久久综合狠狠综合久久综青草 | 伊人一区二区三区久久精品| 欧美日韩精品欧美日韩精品一| 欧美一级二区| 亚洲激情一区| 裸体一区二区三区| 久久精品视频免费播放| 久久精品国产亚洲aⅴ| 亚洲女同在线| 欧美一级网站| 亚洲人成网站影音先锋播放| 在线播放精品| 亚洲人成精品久久久久| 亚洲黄一区二区| 日韩网站免费观看| 一区二区三区高清在线| 亚洲小视频在线观看| 一区二区高清| 亚洲一区二区三区精品在线观看| 亚洲精品影院在线观看| 日韩亚洲视频| 亚洲午夜在线视频| 午夜精品福利在线观看| 午夜欧美精品久久久久久久| 亚洲欧洲日韩在线| 亚洲精品永久免费| 亚洲视频一区二区免费在线观看| 亚洲视频日本| 欧美资源在线观看| 欧美成人一区二区三区片免费| 欧美xart系列高清| 亚洲精品一二区| 亚洲永久免费| 久热国产精品视频| 国产精品草草| 伊人久久av导航| 在线视频你懂得一区二区三区| 欧美一区二区三区播放老司机| 亚洲欧美日韩精品| 久久综合婷婷| 老司机久久99久久精品播放免费| 亚洲欧洲精品一区二区精品久久久 | 另类图片国产| 91久久国产综合久久91精品网站| 99riav国产精品| 久久精品国产99国产精品澳门| 欧美日韩99| 国产一区在线看| 日韩一级黄色大片| 久久嫩草精品久久久久| 这里只有精品电影| 欧美成人自拍视频| 国产一区二区日韩| 日韩一级网站| 欧美激情一区二区三区成人| 亚洲欧美大片| 国产精品啊啊啊| 99视频精品全国免费| 午夜精品免费| 久久久久免费视频| 99国产精品国产精品久久| 久久综合给合久久狠狠狠97色69| 欧美国产综合一区二区| 欧美一区三区二区在线观看| 欧美高清影院| 欧美制服丝袜第一页| 国产精品欧美日韩| 亚洲伊人色欲综合网| 欧美激情偷拍| 一区二区久久| 欧美在线免费播放| 国产精品午夜久久| 亚洲午夜电影在线观看| 亚洲第一精品在线| 久久亚洲不卡| 在线观看日韩精品| 久久久久久久999精品视频| 亚洲性感美女99在线| 欧美亚洲第一区| 亚洲综合色网站| 亚洲性夜色噜噜噜7777| 国产精品区免费视频| 午夜视频一区在线观看| 亚洲图片自拍偷拍| 麻豆91精品| 国产精品视频你懂的| 亚洲女人天堂成人av在线| 亚洲香蕉伊综合在人在线视看| 欧美三区免费完整视频在线观看| 日韩视频一区二区在线观看 | 欧美成人免费在线视频| 久久只精品国产| 亚洲黄色有码视频| 亚洲精品乱码久久久久久按摩观| 欧美另类久久久品| 亚洲在线免费| 午夜激情亚洲| 国色天香一区二区| 亚洲第一区中文99精品| 欧美啪啪一区| 欧美一区2区三区4区公司二百| 亚洲高清视频的网址| 欧美日韩国内| 欧美在线一级va免费观看| 久久av一区| 亚洲精品色图| 亚洲一区二区四区| 影音先锋中文字幕一区| 最近中文字幕日韩精品| 国产精品久在线观看| 久久免费视频在线| 欧美日韩精品二区| 久久久久成人精品免费播放动漫| 欧美资源在线观看| 国产在线精品一区二区夜色| 欧美在线啊v| 亚洲黑丝在线| 亚洲三级免费电影| 国产亚洲精品久久久| 亚洲黄一区二区| 国产精品一区二区三区成人| 亚洲第一天堂av| 国产毛片久久| 最新高清无码专区| 狠狠操狠狠色综合网| 日韩视频在线观看一区二区| 国产资源精品在线观看| 99re在线精品| 国产精品二区在线| 亚洲大胆av| 国产视频一区欧美| 一区二区久久| 亚洲精品欧美日韩专区| 亚洲欧美一区二区原创| 99精品欧美一区二区三区| 久久国内精品自在自线400部| 一区二区免费看| 亚洲摸下面视频| 亚洲视频免费在线观看| 欧美va天堂va视频va在线| 久久久精品tv| 国产精品久久久免费| 亚洲精品色图| 亚洲人成在线观看网站高清| 久久视频国产精品免费视频在线| 久久综合狠狠综合久久综青草| 韩国在线一区| 女仆av观看一区| 99国内精品| 久久精品综合| 亚洲国产一区视频| 欧美伦理影院| 亚洲在线一区| 麻豆精品视频在线观看| 日韩亚洲欧美精品| 国产精品日日摸夜夜添夜夜av| 午夜在线a亚洲v天堂网2018| 男女激情视频一区| 亚洲视频一区二区在线观看 | 亚洲大胆人体在线| 欧美黄色影院| 亚洲先锋成人| 欧美成年人视频网站欧美| 亚洲图片欧洲图片av| 国产九色精品成人porny| 久久成人人人人精品欧| 亚洲精品孕妇| 久久久av毛片精品| 亚洲精品久久嫩草网站秘色| 国产精品www| 蜜桃av一区二区| 亚洲一区在线观看免费观看电影高清| 久久精品九九| 日韩视频在线免费观看| 国产伦精品一区二区三| 六十路精品视频| 亚洲伊人观看| 亚洲电影视频在线| 久久aⅴ国产欧美74aaa| 一区二区高清| 亚洲黑丝在线| 99天天综合性| 亚洲性视频网址| 在线播放不卡| 国产精品一区二区久久久久| 欧美高清在线一区| 欧美一区二区在线视频| 亚洲免费电影在线| 欧美激情导航| 久久偷看各类wc女厕嘘嘘偷窃| 亚洲一区二区三区色| 亚洲国产另类久久久精品极度| 国产精品一区二区三区成人| 欧美日韩国产成人精品| 欧美成人午夜剧场免费观看| 久久激情五月丁香伊人| 欧美一区二区三区精品 | 午夜免费久久久久| 亚洲一区二区在线看|