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

歸去來兮

 

2008年12月30日

Effective C++讀書筆記之三 :確定對象被使用前已先被初始化

關于對象初始化,c++似乎反復無常,例如:
int x;
在某些語境條件下保證初始化為0,而在另外一些語境下卻并沒有這個保證。而下邊這種情況:
class Point{
int x,y;
}
;

Point p;
p的成員函數(shù)有的時候被初始化(0),有的時候沒有被初始化。
現(xiàn)在,已經(jīng)有了一些規(guī)則,對象的初始化何時會發(fā)生,何時不會發(fā)生。但是這些規(guī)則過于復雜,對我們的記憶有一定的挑戰(zhàn),哈哈。
通常如果使用C part of C++而且初始化可能招致運行期成本,那就不保證發(fā)生初始化。一旦進入non-C parts of C++,規(guī)則有一些變化。這就是為啥array(C part of C++)不保證其內(nèi)容被初始化,而vector(STL part of C++)卻有此保證。
我們的最佳處理狀態(tài)是,在使用任何對象之前先將它初始化。對于無任何成員的內(nèi)置類型,必須手動完成此事:
int x = 0;   //對int進行初始化;
const char *text = " A C-style string";   //對指針進行初始化;
double d;
std::cin 
>> d;   //采用input stream的方式完成初始化;
至于內(nèi)置類型以外的其他類型,初始化的責任落在了構造函數(shù)身上。規(guī)則很簡單:確保構造函數(shù)都將對象的每一個成員初始化。
這個規(guī)則很容易奉行,值得注意的是別混淆了賦值(assignment)和初始化(initialization)。考慮一個表現(xiàn)通訊簿的class:
class PhoneNumber{};
class ABEntry{    //Address Book Entry;
public:
ABEntry(
const std::string &name, const std::string &address, const std::list<PhoneNumber> &phones);
private:
std::
string theName;
std::
string tehAddress;
std::list
<PhoneNumber> thePhones;
int numTimesConsulted;
}
;

ABEntry::ABEntry(
const std::string &name, const std::string &address, std::list<PhoneNumber> &phones)
{//以下全是賦值(assignment),不是初始化(initialization);
theName = name;
theAddress 
= address;
thePhones 
= phones;
numTimesConsulted 
= 0;
}
ABEntry對象會帶給你期望的值,但不是最佳做法。C++規(guī)定:對象成員變量的初始化動作發(fā)生在進入構造函數(shù)本體之前。在ABEntry構造函數(shù)內(nèi),theName, theAddress, thePhone都不是被初始化,而是被賦值。初始化的時間發(fā)生的更早,發(fā)生于這些成員函數(shù)的default構造函數(shù)被自動調(diào)用之時(比進入ABEntry構造函數(shù)本體的時間更早)。但這對numTimesConsulted不為真,因為他屬于內(nèi)置類型,不保證在你看到的那個賦值動作的時間點之前獲得初值。
ABEntry構造函數(shù)的一個較好寫法是,使用所謂的member initializatin list(成員函數(shù)初始列)替換賦值動作:
ABEntry::ABEntry(const std::string &name, const std::string &address,
 
const std::list<PhoneNumber> &phones)
: theName(name),
 theAddress(address),
 thePhones(phones), 
numTimesConsulted(
0)
{}//構造函數(shù)本體不需要任何動作
這個構造函數(shù)和上一個的結果相同,但是通常效率較高。基于賦值的那個版本首先調(diào)用default構造函數(shù)為theName, theAddress,和thePhones設立初值,然后立刻再對他們賦值。default的一切作為此刻都浪費了。成員初始列(member initianlization list)的做法避免了這一問題,因為初始列中針對各個變量設的實參,被拿去作為各個成員函數(shù)的實參。本例中theName以name為初值進行copy構造,theAddress以address為初值進行copy構造,thePhones以phones為初值進行copy構造。
對于大多數(shù)類型而言,比起先調(diào)用default構造函數(shù)再調(diào)用copy assignment操作符,單只調(diào)用一次copy構造函數(shù)是比較高效的,有事甚至高的多。對于內(nèi)置類型,如numTimesConsulted,其初始化成本和賦值的成本相同,但為了一致性最好也通過成員初始列來進行初始化。同樣道理,如果我們想default構造一個成員變量,也可以使用成員初始列,只要指定nothing作為初始化列就行了,假設ABEntry有一個無參構造構造函數(shù),我們可以實現(xiàn)如下:
ABEntry::ABEntry()
:theName(),             
//調(diào)用theName的構造函數(shù)
theAddress(),           //調(diào)用theAddress的構造函數(shù)
thePhones(),            //調(diào)用thePhomes的構造函數(shù)
numTimesConsulted(0)    //記得將此內(nèi)置類型顯式定義為0
{}
此處記得一條規(guī)則,那就是在成員初始列中列出所有的成員變量,以免還得記住哪些成員變量可以無需初值。舉個例子,如numTimesConsulted屬于內(nèi)置類型,如果(member initialization list)遺漏了他,他就沒有初值,因而可能開啟“不明確行為”的潘多拉盒子。
有些情況下,即使面對的是內(nèi)置類型,也一定要使用初始列。如果成員變量是const或者reference,他們一定得需要賦初值,而不是賦值。為避免成員變量何時必須在成員初始列中初始化,何時不需要,最簡單的做法就是:總是使用成員初始列。
C++有著十分固定的“成員初始化次序”。是的,次序總是相同的:base classes總是先于derived classes被初始化,而class的成員變量總是以其聲明次序被初始化。讓我們在看一下ABEntry,其theName永遠先被初始化,然后是theAddress,之后thePhones,最后是numTimesConsulted,即使他們在member initialization list中以不同的順序出現(xiàn),也不會有任何影響。為了避免迷惑,你在member initialization list中條列各個成員時,最好總是以其聲明次序為次序。
一旦我們已經(jīng) 很小心的將內(nèi)置型成員變量明確的加以初始化,而且也確保構造函數(shù)運用member initialization list初始化base classes和成員變量,那就剩下唯一的一件事情需要操心,就是:不同編譯單元內(nèi)定義之non-local static對象的初始化次序。
所謂static對象,其壽命從被構造出來直到程序結束為止,因此stack和heap_based對象都被排除。這里所說的static對象包括global對象,定義于namespace對象內(nèi)的對象,在class內(nèi),在函數(shù)內(nèi),以及在file內(nèi)被聲明為static的對象。函數(shù)內(nèi)的static對象稱為local static對象,其他則成為non-local static對象,程序結束時static對象會自動銷毀,也就是他們的析構函數(shù)會在main()結束時被調(diào)用。
所謂編譯單元(translation unit)是指產(chǎn)生單一目標文件(single object file)的那些源碼。基本上是單一源碼文件加上其所包含的頭文件。
現(xiàn)在,上面所涉及到的問題至少包括兩個源碼文件,每一個內(nèi)含至少一個non-local static對象(也就是說對象是global,或者位于namespace內(nèi),或者class內(nèi),或者file作用域內(nèi)被聲明為static)。問題是:如果某個編譯單元內(nèi)的某個non-local static對象的初始化動作使用了另外一個編譯單元內(nèi)的non-local static對象,他所使用的這個對象可能沒有初始化,因為C++對“不同編譯單元內(nèi)的non-local static 對象”的初始化次序并沒有明確定義。
來個例子:
 假設有一個FileSystem class,它讓互聯(lián)網(wǎng)上的文件看起來像是本機。由于這個class使世界看起來像個單一文件系統(tǒng),可能會產(chǎn)生一個特殊對象,位于global或namespace作用域內(nèi),象征單一文件系統(tǒng):
class FileSystem{
public:

std::size_t numDisks() 
const;

}
;
extern FileSystem tfs;//預備給客戶使用的對象,tfs代表"the file system"
FileSystem對象絕不是一個無關痛癢的對象,因此客戶如果在theFileSystem對象構造完成前就使用他,會得到慘重的代價:
現(xiàn)在假設建立了一個class用以處理文件系統(tǒng)內(nèi)部的目錄。很自然,他們會用上theFileSystem的對象:
class Directory{
public:
Directory();

}
;
Directory::Directory()
{

std::size_t disks 
= tfs.numDisks();

}
進一步假設,這些客戶決定創(chuàng)建一個directory對象,用來放置臨時文件:
Directory tempDir(params);//為臨時文件而做出的目錄
現(xiàn)在,初始化的重要作用顯示出來了,除非tfs在tempDir之前被初始化,否則tempDir的構造函數(shù)會用到尚未初始化的tfs。但是tfs和tempDir是不同的人在不同的時間創(chuàng)建出來的,他們是定義于不同編譯單元內(nèi)地non-local static對象,如何能確認tfs在tempDir之前先被初始化?
哦,這是無法確認的。
一個小小的設計可以改變這種情形:將每一個non-local static 對象搬到自己的專屬函數(shù)內(nèi)(該對象在此函數(shù)內(nèi)被聲明為static)。這些函數(shù)返回一個reference用來指向他所包含的對象。然后用戶調(diào)用這些函數(shù),而不是直接指涉這些對象。換句話就是non-local static對象被local static對象替換了。這個實現(xiàn)的基礎在于:C++保證,函數(shù)內(nèi)的non-local static 對象會在函數(shù)被調(diào)用期間首次遇上該對象之定義式時被初始化。所以如果以函數(shù)調(diào)用替換直接訪問non-local static 對象,就獲得了保證,保證所得的那個reference將指向一個經(jīng)歷初始化的對象。 此技術實現(xiàn)于上面的代碼如下:
class FileSystem{};//同前
FileSystem &tfs()//這個函數(shù)用來替換tfs對象;他在FileSystem中可能是個static。
{
static FileSystem fs;
return fs;
}

class Directory{};
Directory::Directory()
{

std::size_t disks 
= tfs().numDisks();

}

Directory 
&tempDir()
{
static Directory td;
return td;
}
修改之后,我們只是使用的是tfs()和tempDir(),而不是tfs和tempDir。也就是使用的是指向static的reference而不是static對象自身。
這樣的reference-returning函數(shù)往往十分單純:第一行定義并初始化一個local static對象,第二行返回他。當然,他是絕佳的inline候選,特別是經(jīng)常被調(diào)用的話。但是,另一方面,任何一種non-const static對象,不論是local或者non-local,在多線程下“等待某事發(fā)生都會有麻煩的。處理這個麻煩的一種做法是:在程序的單線程啟動階段手工調(diào)用所有的reference-returning函數(shù)(??),這可消除與初始化有關的race condition。
為避免對象初始化之前過早的使用他們,你需要做的是三件事:手工初始化內(nèi)置的non-member對象;使用member initialization list;在初始化次序不確定下加強你的設計。


Things to remember:
1.Manually initialize objects of built-in type, because C++only sometimes initializes them itself;
2.In a constructor, prefer to use the member initialization list to assigenment inside the body of the constructor. List data member in the initialization list in the same order they're declared  in the class.
3.Avoid initialization order problems across translation units by replacing non-local static objects with local static objects.

posted @ 2008-12-30 11:06 Edmund 閱讀(379) | 評論 (0)編輯 收藏

2008年12月9日

Effective C++讀書筆記之二 :盡可能使用const

條款三:盡可能使用const(use const whenever possible)
const允許你指定一個語義約束,而編譯器會強制實施這項約束。它允許你告訴編譯器和其他程序員某值應該保持不變。有一條約束需要注意,那就是:如果const出現(xiàn)在*號的左邊,那就是說被指物是常量;如果出現(xiàn)在星號右邊,則表示指針本身是常量;如果出現(xiàn)在兩邊,則被指物和指針都是常量。如果被指物是常量,則關鍵字const寫在類型的前面和類型之后,星號之前兩種所表示的語義是相同的。例如下面這兩種寫法是一樣的:
void f1(const Widget* pw);
void f2(Widget const * pw);
const也可用來修飾STL中的迭代器。聲明迭代器為const就想聲明指針為const一樣(即T* const 指針),表示這個迭代器不得指向不同的東西。但它所指的東西的值是可以改變的。如果希望迭代器所指的東西不可改變(即模擬一個const T*指針),需要的是const_iterator:
std::vector<int> vec;
...
const std::vector<int>::iterator iter = vec.begin();// same as T* const
*iter = 10;                                                        //no problem
++iter;                                                              //wrong!!
std::vector<int>::const_iterator cIter = vec.begin();//same as const T*
*iter = 10;                                                             //wrong!!
++iter;                                                                  //no problem

const 最具威力(?)的用法是面對函數(shù)聲明時的應用。在一個函數(shù)聲明式內(nèi),const可以和函數(shù)返回值,各參數(shù),函數(shù)自身(成員函數(shù))產(chǎn)生關聯(lián)。
令函數(shù)返回一個常量值,往往可以降低因客戶錯誤而造成的意外,而又不至于放棄安全性和高效性。例如,考慮有理數(shù)的operator*聲明式:
class Rational(){...};
const Rational operator* (const Rational & lhs, const Rational & rhs);
也許你會說為什么返回一個const對象?原因是如果不這樣別人可能實現(xiàn)這樣的暴行:
Rational a,b,c;
...
(a*b)=c;
下面,主要說明const作用于成員函數(shù)。
許多人都忽視了這么一個事實,那就是如果兩個成員函數(shù)只是常量性不同,那么他們是可以重載的。考慮以下這個用來表示一大塊文字的class:

class TextBlock{
public:

const char& operator[](std::size_t position) const
{return text[position];}
char& operator[](std::size_t position)
{return text[position];}
private:
std::
string text;
}
;
TextBlock的operator[]可以這么使用:
TextBlock tb(
"Hello");
std::cout 
<< tb[0];  //調(diào)用non-const 

const TextBlock ctb("Hello");
std::cont 
<< ctb[0]; //調(diào)用const

真是情形中const對象多用于passed by pointer-to-const或passed by reference-to-const的傳遞結果。上述的ctb太過于造作,下邊這個比較真實:
void print (const TextBlocd& ctb)
{
  std::cout 
<< ctb[0];
  
}

只用重載operator[]并對不同的版本給予不同的返回類型,就可以令const和non-const獲得不同的處理。
此處需要注意一點,non-const operator[]的返回類型是個reference to char,不是char。如果operator[]返回的是個char,下邊的賦值就不能通過編譯:
tb[0] = 'x'; //error c2106: ' = ' : left operand must be l-value
那是因為,如果函數(shù)的返回類型是個內(nèi)置類型,那么改動函數(shù)的返回值從來就不合法。縱使合法,C++以by value返回對象這一事實(條款20)意味著改動的其實只是tb.text[0]的一個副本,不是tb.text[0]本身,那不是我們想要的結果。
下邊來說說在const和non-const成員函數(shù)中避免重復
假設TextBlock(和CTextBlock)內(nèi)的operator[]不單只是返回一個reference指向某字符,也執(zhí)行邊界檢查、志記訪問信息、甚至可能進行數(shù)據(jù)完整性檢驗。把所有這些同時放進const和non-const operator[]中,導致這樣的一個怪物:
class TextBlock{
public:

const char& operator[](std::size_t position) const
{
      
//邊界檢查(bounds checking)
      //志記數(shù)據(jù)訪問(log access data)
      //檢驗數(shù)據(jù)完整性(verify data integrity)
return text[position];
}

char& operator[](std::size_t position)
{
      
//邊界檢查(bounds checking)
      //志記數(shù)據(jù)訪問(log access data)
      //檢驗數(shù)據(jù)完整性(verify data integrity)
return text[position];
}

private:
std::
string text;
}
;
其中代碼的代碼重復性及伴隨的編譯時間,維護,代碼膨脹等問題真是令人頭疼啊。當然了,將邊界檢查……等所有代碼移植到另一個成員函數(shù),并令兩個版本的operator[]調(diào)用它,是可能的,但是還是重復了一些代碼,例如函數(shù)調(diào)用,兩次return語句等。
我們真正要做的,是實現(xiàn)operator[]的機能一次并使用它兩次。也就是說,你必須使一個調(diào)用另一個。這促使我們將常量性轉除(casting away constness)。
就一般而言,casting是一個糟糕的想法,在條款27中有詳細的說明。然而代碼重復也不是什么令人愉快的經(jīng)驗。本例中cosnt operator[]完全做掉了non-const版本該做的一切,唯一不同是其返回類型多了一個const資格修飾。這種情況下如果將返回值的const轉除是安全的,因為不論誰調(diào)用non-const operator[]都一定首先有個non-const對象,否則就不能夠調(diào)用non-const函數(shù)。所以令non-const operator[]調(diào)用其const兄弟是一個避免重復的安全做法:
class TextBlock{
public:

const char& operator[](std::size_t position) const
{



return text[position];
}

char& operator[](std::size_t position)
{
const_cast
<char&>(static_cast<const TextBlock&>
(
*this)[position]);
}


}
;
這里面有兩個轉型動作,而不是一個。我們打算讓non-const operator[]調(diào)用const兄弟,但是non-const如果只是單純調(diào)用operator[],會遞歸調(diào)用自己。為了避免無窮遞歸,我們必須明確指出調(diào)用的是const operator[]。因此,這里將*this從其原始類型TextBlock&轉型為const TextBlock&。所以這里有兩次轉型:第一次用來為*this添加const,第二次則是從const operator[]的返回值中移除const。添加const的那一次轉型強迫進行了一次安全轉型,所以采用static_cast。移除const的那個動作只能由const_cast完成,沒有其他選擇。
下面來考慮一下反向的做法:令const來調(diào)用non-const以避免重復。這個不是我們應該做的。const成員函數(shù)承諾絕對不改變其對象的邏輯狀態(tài),non-const成員函數(shù)卻沒有這般承諾。如果在const函數(shù)內(nèi)部調(diào)用了non-const函數(shù),就是冒了這樣的風險:你曾經(jīng)承諾不改動的那個對象被改動了。這就是為什么“const成員函數(shù)調(diào)用non-const成員函數(shù)”是一種錯誤行為:因為對象有可能因此而被改動。反向調(diào)用才是安全的:non-const函數(shù)本來就可以對其對象做任何動作,所以在其中調(diào)用一個const成員函數(shù)并不會帶來任何風險。

本條目總結:

Things to Remember

  • Declaring something const helps compilers detect usage errors. const can be applied to objects at any scope, to function parameters and return types, and to member functions as a whole.

  • Compilers enforce bitwise constness, but you should program using conceptual constness.

  • When const and non-const member functions have essentially identical implementations, code duplication can be avoided by having the non-const version call the const version.

posted @ 2008-12-09 23:00 Edmund 閱讀(283) | 評論 (0)編輯 收藏

2008年12月8日

effectiv c++ 讀書筆記之一

開始寫effective c++的讀書筆記。今天是條款2:盡量以const,enum,inline替換#define(prefer consts,enums,and inlines to #define.)
現(xiàn)在在維護代碼的時候,前輩們大片大片的宏搞得我是那個暈頭轉向啊,真希望他們也看過本條款
1.Case:#define ASPECT_RATIO 1.653
   Recommendation:const double AspectRatio = 1.653;
Reason:   當使用ASPECT_RATIO但是獲得一個編譯錯誤信息時,可能你會很是發(fā)冏,因為這個錯誤信息也許會提到1.653而不是ASPECT_RATIO。如果ASPECT_RATIO定義在非你所寫的頭文件中,你更是因為追蹤他而浪費時間。改為推薦的方式后,你找到的肯定是AspectRatio。當以常量替換#define時,有兩種注意的情況,第一種是定義常量指針(const pointers)。由于常量定義式常放在頭文件內(nèi),因此有必要將指針也聲明為const。例如在一個頭文件內(nèi)定義一個常量的char*-based字符串,必須寫const兩次:
const char* const authorName = "Edmund";
這里采用string對象比其前輩char*-based更合適,
const std::string authorName("Edmund");
第二種是class專屬常量。為了將常量的作用域限制在class內(nèi),你必須讓他成為class的一個成員;而為確保此常量只有一個實體,則必須聲明為static:
class GamePlayer{
private:
static const int NumTurns = 5;
int scores[NumTurns];
...
}
然而,你看到的是NumTurns的聲明式而不是定義式,C++通常要求我們所使用的任何東西都要有一個定義式,但如果他是個class的專屬常量而又是static且為整數(shù)類型(ints,chars,bools),則做特殊處理。只要不取他們的地址,你可以聲明并使用他們而無需提供定義式。但如果取某個class專屬常量的地址,或縱使不取地址而編譯器卻堅持要看到一個定義式,你就必須提供另外一個定義式:
const int GamePlayer::NumTurns;
由于NumTurns在聲明時已經(jīng)獲得了初值,因此定義時不可以再設初值。此外,對所謂的“in-class初值設定”也只允許對整數(shù)常量進行。如果為非整型則可以采用下面的這種方式:
class CostEstimate{
private:
static const double FudgeFactor;
...
}

const double CostEstimate::FudgeFactor = 1.35;
當你在編譯期需要一個class常量值,例如在上述GamePlayer::scores的數(shù)組聲明中,此時如果編譯器不允許“static整數(shù)型class常量”完成“in-class初值設定”,可采用enum來解決,其理論基礎是“一個屬于枚舉類型的數(shù)值可權充ints被使用”,于是GamePlayer可定義如下:
class GamePlayer{
private:
enum{NumTurns = 5};
int scores[NumTurns];
...
};
注意:取一個const的值是合法的,但是取一個enum的值就是不合法的,取一個#define的值也是不合法的。如果你不想讓別人獲得一個pointer或者reference指向你的某個整數(shù)常量,enum可以幫助你實現(xiàn)這個約束。
下邊繼續(xù)說預處理器。另外一個常見的#define誤用的情景是以他來實現(xiàn)宏,宏看起來像函數(shù),但是不會招致函數(shù)調(diào)用帶來的額外開銷,例如:
#define CALL_WITH_MAX(a,b) f((a)>(b)?(a):(b))。他的缺點就不說了,替代方式:
template<class T> inline void callWithMax(const T& a, const T& b)
{
f(a > b?a : b);
}
本條目總結:
1.對于單純常量,最好以const對象或者enums替換#defines;
2.對于形似函數(shù)的宏,最好改用inline函數(shù)替換#defines。




Ps:本文是第一次在cppblog上發(fā)表的文章,呵呵。很早就想在這上面寫點了,但是不是忙這就是忙那,昨天下定決心,先把effective C++(3e)里面的55條讀書筆記寫在這上面。打算每天一個條目,這里面好多跟書上的句子一樣,但是全是我自己敲進去的,不存在任何的paste。所寫均是自己搞清楚的,不明白地方的暫時沒有添加。

posted @ 2008-12-08 23:50 Edmund 閱讀(286) | 評論 (0)編輯 收藏

僅列出標題  

導航

統(tǒng)計

常用鏈接

留言簿(1)

隨筆分類

隨筆檔案

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久久97精品| 欧美一区二区三区四区夜夜大片| 欧美激情视频给我| 欧美国产第二页| 欧美激情视频一区二区三区不卡| 欧美va日韩va| 欧美吻胸吃奶大尺度电影| 国产精品亚洲美女av网站| 国产精品观看| 欧美视频在线一区| 国产精品午夜在线观看| 一区二区三区欧美在线| 午夜在线精品| 久久深夜福利免费观看| 欧美高清在线播放| 中日韩高清电影网| 久久久97精品| 欧美深夜福利| 一区在线播放| 亚洲欧美国产三级| 免费观看亚洲视频大全| 一区二区高清在线观看| 久久久久亚洲综合| 欧美午夜精品伦理| 亚洲激情视频网站| 久久精品99国产精品| 亚洲精品日日夜夜| 久久久久久综合网天天| 欧美性猛交xxxx免费看久久久| 狠狠色伊人亚洲综合网站色| 一区二区三区蜜桃网| 久久综合精品国产一区二区三区| 亚洲美女av在线播放| 久久久久一区二区| 国产欧美在线视频| 国产偷久久久精品专区| 国产精品嫩草影院av蜜臀| 亚洲一区国产| 久久综合网hezyo| 国产欧美不卡| 亚洲视频欧美视频| 亚洲国产人成综合网站| 欧美在线高清视频| 国产精品福利网站| 99国产精品久久久久久久| 免费观看在线综合色| 性欧美大战久久久久久久久| 欧美理论在线播放| 亚洲精品小视频| 欧美国产亚洲精品久久久8v| 久久精品一区蜜桃臀影院 | 老司机免费视频久久| 亚洲色无码播放| 欧美日韩免费在线| 亚洲特级毛片| 亚洲一区二区三区高清| 国产精品福利网| 午夜亚洲精品| 午夜在线播放视频欧美| 国产视频久久久久久久| 久久久91精品国产一区二区精品| 亚洲自拍偷拍视频| 国产婷婷一区二区| 久久全国免费视频| 在线天堂一区av电影| 欧美精品亚洲一区二区在线播放| 一区视频在线播放| 欧美成人午夜激情视频| 久久综合五月天婷婷伊人| 在线免费观看欧美| 欧美国产精品专区| 欧美精品电影| 宅男噜噜噜66国产日韩在线观看| 亚洲裸体在线观看| 国产精品久久久久秋霞鲁丝| 香蕉久久精品日日躁夜夜躁| 久久成人资源| 久久人人九九| 欧美激情亚洲激情| 亚洲精品久久久蜜桃| 最新亚洲激情| 国产精品进线69影院| 欧美一区免费视频| 欧美一区二区成人| 亚洲黄色成人久久久| 一区二区不卡在线视频 午夜欧美不卡在| 欧美日韩亚洲国产一区| 欧美伊人精品成人久久综合97| 久久爱www久久做| 亚洲国产日韩一级| 亚洲午夜久久久| 亚洲高清一二三区| 亚洲午夜一二三区视频| 黄网站色欧美视频| 99综合视频| 久久国产一区二区三区| 欧美第一黄网免费网站| 小处雏高清一区二区三区| 久久视频在线视频| 午夜激情一区| 欧美国产大片| 久久免费国产| 国产精品久久午夜| 亚洲国产精品久久久久婷婷老年| 国产精品网红福利| 最近中文字幕日韩精品| 国产日韩一区在线| 99精品欧美一区| 亚洲欧洲在线免费| 久久精品视频在线播放| 亚洲欧美日韩一区二区| 欧美精品日日鲁夜夜添| 玖玖在线精品| 国产亚洲精品一区二区| 亚洲综合精品一区二区| 一区二区三区国产| 欧美大片一区| 亚洲二区视频| 亚洲国产精品t66y| 久久精品在线免费观看| 欧美怡红院视频| 国产精品久久二区二区| 日韩视频中文| av成人免费观看| 美女999久久久精品视频| 亚洲一区综合| 99精品福利视频| 免费视频一区| 欧美高清视频免费观看| 一区免费视频| 免费中文字幕日韩欧美| 蜜臀久久99精品久久久画质超高清 | 麻豆国产精品777777在线| 久久狠狠婷婷| 国产欧美日韩一区二区三区在线| 在线视频一区二区| 亚洲免费在线电影| 国产精品视频在线观看| 亚洲一区二区视频在线| 欧美一区二区三区视频在线| 国产精品久久一级| 亚洲午夜在线视频| 久久精品免视看| **网站欧美大片在线观看| 久久综合婷婷| 亚洲人成人一区二区三区| 亚洲免费观看高清完整版在线观看熊| 欧美va亚洲va日韩∨a综合色| 亚洲夫妻自拍| av成人免费| 国产精品夜色7777狼人| 久久精品国产999大香线蕉| 免费欧美在线视频| 99成人在线| 国产乱码精品一区二区三区忘忧草| 亚洲综合大片69999| 久久亚洲一区二区三区四区| 亚洲第一天堂av| 欧美日韩国产小视频在线观看| 亚洲私人影院在线观看| 久久蜜桃精品| 一区二区久久久久| 国产欧美一区二区精品性| 久久免费观看视频| 99在线观看免费视频精品观看| 欧美一级久久久| 91久久精品久久国产性色也91| 欧美日韩国产片| 久久成人精品无人区| 亚洲欧洲精品一区二区三区不卡 | 在线视频中文亚洲| 午夜久久久久久久久久一区二区| 国产无一区二区| 另类天堂av| 亚洲欧美乱综合| 亚洲高清久久久| 欧美一区二视频| 一本综合精品| 亚洲国产成人午夜在线一区| 国产精品久久久久久av下载红粉| 久久天堂国产精品| 午夜视频一区二区| 亚洲日本va午夜在线电影| 亚洲精品久久嫩草网站秘色 | 巨乳诱惑日韩免费av| 亚洲欧洲一区二区三区| 国产欧美精品va在线观看| 美女被久久久| 久久精品国产综合| 亚洲综合日韩中文字幕v在线| 欧美国产日本高清在线| 久久久久久久激情视频| 亚洲欧美国产另类| 一区二区高清在线| 亚洲黄色尤物视频| 激情婷婷欧美| 国产主播一区| 国产日韩欧美视频在线| 国产精品国产福利国产秒拍| 欧美黄免费看|