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

旅途

如果想飛得高,就該把地平線忘掉

c++中const的完全解析

http://blog.csdn.net/jsjwql/archive/2007/09/10/1779516.aspx

1.?? const
類型定義:指明變量或對象的值是不能被更新 , 引入目的是為了取代預編譯指令

2.?? 可以保護被修飾的東西,防止意外的修改,增強程序的健壯性。

3.?? 編譯器通常不為普通 const 常量分配存儲空間,而是將它們保存在符號表中,這使得它成為一個編譯期間的常量,沒有了存儲與讀內存的操作,使得它的效率也很高。

4.??? 可以節省空間,避免不必要的內存分配。

? 例如:

???? #define PI 3.14159???????? file:// 常量宏

???? const doulbe? Pi=3.14159;? file:// 此時并未將 Pi 放入 ROM

??????? ......

???? double i=Pi;???????????? file:// 此時為 Pi 分配內存,以后不再分配!

???? double I=PI;?????????????? file:// 編譯期間進行宏替換,分配內存

???? double j=Pi;?????????????? file:// 沒有內存分配

???? double J=PI;?????????????? file:// 再進行宏替換,又一次分配內存!

?const 定義常量從匯編的角度來看,只是給出了對應的內存地址,而不是象 #define 一樣給出的是立即數,所以, const 定義的常量在程序運行過程中只有一份拷貝,而 #define 定義的常量在內存中有若干個拷貝。

?

對于基本聲明

1.? const int r=100; // 標準 const 變量聲明加初始化,因為默認內部連接所以必須被初始化,其作用域為此文件,編譯器經過類型檢查后直接用 100 在編譯時替換

?

2.? extend const int r=100; // const 改為外部連接,作用于擴大至全局,編譯時會分配內存,并且可以不進行初始化,僅僅作為聲明,編譯器認為在程序其他地方進行了定義

但是如果外部想鏈接 r ,不能這樣用

extern const int r=10;? // 錯誤!常量不可以被再次賦值

3. const int r[ ]={1,2,3,4};

struct S {int a,b;};

const S s[ ]={(1,2),(3.4)}; // 以上兩種都是常量集合,編譯器會為其分配內存,所以不能在編譯期間使用其中的值,例如: int temp[r[2]]; 這樣的編譯器會報告不能找到常量表達式

? 但是

?const int Max=100;

?int Array[Max];?

正確。

?還有

?

? 定義數組必須用常量,可以用 const 或者 #define 定義。 Static 雖然是編譯時確定,也不能用來聲明數組。

?

對于指針和引用

1.?? const int *r=&x; // 聲明 r 為一個指向常量的 x 的指針, r 指向的對象不能被修改,但他可以指向任何地址的常量

pointer const 可以指定普通變量 , 用改指針不能修改它指向的對象,并不表示指向的對象是 const 不能被改變,例如:

int i = 10;

const int * p =? &i;

*p = 11; //wrong

?

?i = 11 ; //correct

自己的一個經驗:一個具體的概念可以用范型的概念來賦值,但是一個范型的概念不能用具體的概念來賦值。

我們可以把 const 指針當成普通指針的父類,因為普通指針改寫了 const 屬性,而具有比 const 指針更多的功能。 這樣的話只有父類指針可以指向子類,而子類指針不能指向父類。

2.?? int const *r=&x; // 與用法 1 完全等價,沒有任何區別

3.?? int * const r=&x; // 聲明 r 為一個常量指針,他指向 x r 這個指針的指向不能被修改,但他指向的地址的內容可以修改

4.? const int * const r=&x; // 綜合 1 3 用法, r 是一個指向常量的常量型指針

5.?? const double & v;????? 該引用所引用的對象不能被更新

? 引用必須定義是初始話,而且初始化后這個引用不能指向其他的對象。但是這里加的 const 聲明不是這個意思,它是指不能改變 v 引用對象本身,也就是只能調用該對象里面的 const 成員函數。

?

對于類型檢查

可以把一個非 const 對象賦給一個指向 const 的指針,因為有時候我們不想從這個指針來修改其對象的值;但是不可以把一個 const 對象賦值給一個非 const 指針,因為這樣可能會通過這個指針改變指向對象的值,但也存在使這種操作通過的合法化寫法,使用類型強制轉換可以通過指針改變 const 對象:

const int r=100;

int * ptr = const_cast<int*>(&r);? //C++ 標準, C 語言使用: int * ptr =(int*)&r;

?

對于字符數組

?

char * name = “china”; 這樣的語句,在編譯時是能夠通過的,但是 ”china” 是常量字符數組,任何想修改他的操作也能通過編譯但會引起運行時錯誤,如果我們想修改字符數組的話就要使用 char name[ ] = “china”; 這種形式。

?

對于函數

1. void Fuction1 ( const int r ); // 此處為參數傳遞 const 值,意義是變量初值不能被函數改變

2. const int Fuction1 (int); // 此處返回 const 值,意思指返回的原函數里的變量的初值不能被修改,但是函數按值返回的這個變量被制成副本,能不能被修改就沒有了意義,它可以被賦給任何的 const 或非 const 類型變量,完全不需要加上這個 const 關鍵字。但這只對于內部類型而言(因為內部類型返回的肯定是一個值,而不會返回一個變量,不會作為左值使用),對于用戶自定義類型,返回值是常量是非常重要的,見下面條款 3

3.? Class CX; // 內部有構造函數,聲明如 CX(int r =0)

CX? Fuction1 () { return CX(); }

const CX Fuction2 () { return CX(); }

如有上面的自定義類 CX ,和函數 Fuction1() Fuction2(), 我們進行如下操作時:

Fuction1() = CX(1); // 沒有問題,可以作為左值調用

Fuction2() = CX(1); // 編譯錯誤, const 返回值禁止作為左值調用。因為左值把返回值作為變量會修改其返回值, const 聲明禁止這種修改。

4. ? 函數中指針的 const 傳遞和返回:

int F1 (const char * pstr); // 作為傳遞的時候使用 const 修飾可以保證不會通過這個指針來修改傳遞參數的初值,這里在函數內部任何修改 *pstr 的企圖都會引起編譯錯誤。

const char * F2 (); // 意義是函數返回的指針指向的對象是一個 const 對象,它必須賦給一個同樣是指向 const 對象的指針。

const char * const F3(); // 比上面多了一個 const ,這個 const 的意義只是在他被用作左值時有效,它表明了這個指針除了指向 const 對象外,它本身也不能被修改,所以就不能當作左值來處理。

5.?? 函數中引用的 const 傳遞:

void F1 ( const X& px); // 這樣的一個 const 引用傳遞和最普通的函數按值傳遞的效果是一模一樣的,他禁止對引用的對象的一切修改,唯一不同的是按值傳遞會先建立一個類對象的副本,然后傳遞過去,而它直接傳遞地址,所以這種傳遞比按值傳遞更有效。

** 另外只有引用的 const 傳遞可以傳遞一個臨時對象,因為臨時對象都是 const 屬性,且是不可見的,他短時間存在一個局部域中,所以不能使用指針,只有引用的 const 傳遞能夠捕捉到這個家伙。

6.? 有一點可以注意一下

??? const 為函數重載提供了一個參考。

???????? class A

???????? {

?????????? ......

?????????? void f(int i)?????? {......} file:// 一個函數

?????????? void f(int i) const {......} file:// 上一個函數的重載

??????????? ......

????????? };

?

??????? 關于函數 overloading 不能根據返回值類型來確定

?

?? ?????double max( int a, int b);

??????? int??????? max( int a, int b);

??????? 也不能根據參數的默認值來判斷

??????? int max( int a, int b);

??????? int max( int a, int b, int c=12);

??????? 一句話不能讓編譯器有多個選擇就 ok

?

對于類

1. ? 首先,對于 const 的成員變量,只能在構造函數里使用初始化成員列表來初始化,試圖在構造函數體內進行初始化 const 成員變量會引起編譯錯誤。初始化成員列表形如:

X:: X ( int ir ): r(ir) {} // 假設 r 是類 X const 成員變量

2.? const 成員函數。提到這個概念首先要談到 const 對象,正象內置類型能夠定義 const 對象一樣( const int r=10; ),用戶自定義類型也可以定義 const 對象 (const X px(10);) ,編譯器要保證這個對象在其生命周期內不能夠被改變。如果你定義了這樣的一個 const 對象,那么對于這個對象的一切非 const 成員函數的調用,編譯器為了保證對象的 const 特性,都會禁止并在編譯期間報錯。所以如果你想讓你的成員函數能夠在 const 對象上進行操作的話,就要把這個函數聲明為 const 成員函數。假如 f( ) 是類中的成員函數的話,它的聲明形如:

int f( ) const; //const 放在函數的最后,編譯器會對這個函數進行檢查,在這個函數中的任何試圖改變成員變量和調用非 const 成員函數的操作都被視為非法

** 類的構造和析構函數都不能是 const 函數。

3.? 建立了一個 const 成員函數,但仍然想用這個函數改變對象內部的數據。這樣的一個要求也會經常遇到,尤其是在一個苛刻的面試考官那里。首先我們要弄清楚考官的要求,因為有兩種方法可以實現,如果這位考官要求不改變原來類的任何東西,只讓你從當前這個 const 成員函數入手,那么你只有使用前面提到的類型強制轉換方法。實例如下:

// 假如有一個叫做 X 的類,它有一個 int 成員變量 r ,我們需要通過一個 const 成員函數 f( ) 來對這個 r 進行 ++r 操作,代碼如下

void X::f( ) const

{? (const_cast<X*>(this)) -> ++r;? } // 通過 this 指針進行類型強制轉換實現

另外一種方法就是使用關鍵字: mutable 。如果你的成員變量在定義時是這個樣子的:

mutable int r ;

那么它就告訴編譯器這個成員變量可以通過 const 成員函數改變。編譯器就不會再理會對他的檢查了。

?

關于 const 一些問題

?[ 思考 1] 以下的這種賦值方法正確嗎?

?const A_class* c=new A_class();

?A_class* e = c;

這種方法不正確,因為聲明指針的目的是為了對其指向的內容進行改變,而聲明的指針 e 指向的是一個常量,所以不正確;

[ 思考 2] 以下的這種賦值方法正確嗎?

?A_class* const c = new A_class();

?A_class* b = c;

這種方法正確,因為聲明指針所指向的內容可變;

[ 思考 3] 這樣定義賦值操作符重載函數可以嗎?

const A_class& operator=(const A_class& a);

不正確;在 const A_class::operator=(const A_class& a) 中,參數列表中的 const 的用法正確,而當這樣連續賦值的時侯,問題就出現了: A_class a,b,c:(a=b)=c; 因為 a.operator=(b) 的返回值是對 a const 引用,不能再將 c 賦值給 const 常量。

?

?

幾點值得討論的地方:
1 const 究竟意味著什么?
?
說了這么多,你認為 const 意味著什么?一種修飾符?接口抽象?一種新類型?
?
也許都是,在 Stroustup 最初引入這個關鍵字時,只是為對象放入 ROM 做出了一種可能,對于 const 對象, C++ 既允許對其進行靜態初始化,也允許對他進行動態初始化。理想的 const 對象應該在其構造函數完成之前都是可寫的,在析夠函數執行開始后也都是可寫的,換句話說, const 對象具有從構造函數完成到析夠函數執行之前的不變性,如果違反了這條規則,結果都是未定義的!雖然我們把 const 放入 ROM 中,但這并不能夠保證 const 的任何形式的墮落,我們后面會給出具體的辦法。無論 const 對象被放入 ROM 中,還是通過存儲保護機制加以保護,都只能保證,對于用戶而言這個對象沒有改變。換句話說,廢料收集器(我們以后會詳細討論,這就一筆帶過)或數據庫系統對一個 const 的修改怎沒有任何問題。
2 )位元 const V.S. 抽象 const?
對于關鍵字 const 的解釋有好幾種方式,最常見的就是位元 const 抽象 const 。下面我們看一個例子:
??????? class A
??????? {
???????? public:
?????????????? ......
?????????????? A f(const A& a);
?????????????? ......
???????? };
如果采用抽象 const 進行解釋,那就是 f 函數不會去改變所引用對象的抽象值,如果采用位元 const 進行解釋,那就成了 f 函數不會去改變所引用對象的任何位元。
我們可以看到位元解釋正是 c++ const 問題的定義, const 成員函數不被允許修改它所在對象的任何一個數據成員。
為什么這樣呢?因為使用位元 const 2 個好處:
?
最大的好處是可以很容易地檢測到違反位元 const 規定的事件:編譯器只用去尋找有沒有對數據成員的賦值就可以了。另外,如果我們采用了位元 const ,那么,對于一些比較簡單的 const 對象,我們就可以把它安全的放入 ROM 中,對于一些程序而言,這無疑是一個很重要的優化方式。(關于優化處理,我們到時候專門進行討論)
當然,位元 const 也有缺點,要不然,抽象 const 也就沒有產生的必要了。
首先,位元 const 的抽象性比抽象 const 的級別更低!實際上,大家都知道,一個庫接口的抽象性級別越低,使用這個庫就越困難。
其次,使用位元 const 的庫接口會暴露庫的一些實現細節,而這往往會帶來一些負面效應。所以,在庫接口和程序實現細節上,我們都應該采用抽象 const 。
有時,我們可能希望對 const 做出一些其它的解釋,那么,就要注意了,目前,大多數對 const 的解釋都是類型不安全的,這里我們就不舉例子了,你可以自己考慮一下,總之,我們盡量避免對 const 的重新解釋。
3 )放在類內部的常量有什么限制?
?
看看下面這個例子:
????class A
????{
??????private:
?????????? const int c3 = 7;?????????? // ???
?? ??? ???static int c4 = 7;????????? // ???
?? ??? ?????static const float c5 = 7;? // ???
????????? ......
? ???};
你認為上面的 3 句對嗎?呵呵,都不對!使用這種類內部的初始化語法的時候,常量必須是被一個常量表達式初始化的整型或枚舉類型,而且必須是 static const 形式。這顯然是一個很嚴重的限制!
?
那么,我們的標準委員會為什么做這樣的規定呢?一般來說,類在一個頭文件中被聲明,而頭文件被包含到許多互相調用的單元去。但是,為了避免復雜的編譯器規則, C++ 要求每一個對象只有一個單獨的定義。如果 C++ 允許在類內部定義一個和對象一樣占據內存的實體的話,這種規則就被破壞了。
4 )如何初始化類內部的常量?
?
一種方法就是 static const 并用,在內部初始化,如上面的例子;
另一個很常見的方法就是初始化列表:
??????class A
????? {
????????? public:
??????????????? A(int i=0):test(i) {}
????????? private:
??????????????? const int i;
???????}
;
??????
還有一種方式就是在外部初始化,例如:
??????class A
??????{
????????? public:
??????????????? A() {}
????????? private:
??????????????? static const int i;? file://注
意必須是靜態的!
???????}

????????? const int A::i=3;
5 )常量與數組的組合有什么特殊嗎?
??
我們給出下面的代碼:
?????????? const int size[3]={10,20,50};
?????????? int array[size[2]];
有什么問題嗎?對了,編譯通不過!為什么呢?
?const
可以用于集合,但編譯器不能把一個集合存放在它的符號表里,所以必須分配內存。在這種情況下, const 意味著 不能改變的一塊存儲 。然而,其值在編譯時不能被使用,因為編譯器在編譯時不需要知道存儲的內容。自然,作為數組的大小就不行了:)
?
你再看看下面的例子:
???????class A
???????{
????????? public:
??????????????? A(int i=0):test[2]({1,2}) {} file://你
認為行嗎?
????????? private:
??????????????? const int test[2];
????????}

vc6
下編譯通不過,為什么呢?
關于這個問題,前些時間, njboy 問我是怎么回事?我反問他: 你認為呢? 他想了想,給出了一下解釋,大家可以看看:我們知道編譯器堆初始化列表的操作是在構造函數之內,顯式調用可用代碼之前,初始化的次序依據數據聲明的次序。初始化時機應該沒有什么問題,那么就只有是編譯器對數組做了什么手腳!其實做什么手腳,我也不知道,我只好對他進行猜測:編譯器搜索到 test 發現是一個非靜態的數組,于是,為他分配內存空間,這里需要注意了,它應該是一下分配完,并非先分配 test[0], 然后利用初始化列表初始化,再分配 test[1], 這就導致數組的初始化實際上是賦值!然而,常量不允許賦值,所以無法通過。
呵呵,看了這一段冠冕堂皇的話,真讓我笑死了! njboy 別怪我揭你短呀:)我對此的解釋是這樣的: C++ 標準有一個規定,不允許無序對象在類內部初始化,數組顯然是一個無序的,所以這樣的初始化是錯誤的!對于他,只能在類的外部進行初始化,如果想讓它通過,只需要聲明為靜態的,然后初始化。
?
這里我們看到,常量與數組的組合沒有什么特殊!一切都是數組惹的禍!
6 this 指針是不是 const 類型的?
?this
指針是一個很重要的概念,那該如何理解她呢?也許這個話題太大了,那我們縮小一些: this 指針是個什么類型的?這要看具體情況:如果在非 const 成員函數中, this 指針只是一個類類型的;如果在 const 成員函數中, this 指針是一個 const 類類型的;如果在 volatile 成員函數中 ,this 指針就是一個 volatile 類類型的。
7 const 到底是不是一個重載的參考對象?
???????
先看一下下面的例子:
??????? class A
???????? {
??????????????? ? ......
?????????? ???? void f(int i)?????? {......} file://一
個函數
?????????? ???? void f(int i) const {......} file://上
一個函數的重載
??????????? ??? ......
????????? };
???????
上面是重載是沒有問題的了,那么下面的呢?
???????? class A
???????? {
??????????????? ......
?????????? ???? void f(int i)?????? {......} file://一
個函數
??????????????? void f(const int i) {......} file://?????
??????????????? ? ......
???????? };
這個是錯誤的,編譯通不過。那么是不是說明內部參數的 const 不予重載呢?再看下面的例子:
??????? class A
???????? {
??????????????? ......
?????????? ???? void f(int& )?????? {......} file://一
個函數
??????????????? void f(const int& ) {......} file://?????
??????????????? ......
???????? };
?
這個程序是正確的,看來上面的結論是錯誤的。為什么會這樣呢?這要涉及到接口的透明度問題。按值傳遞時,對用戶而言,這是透明的,用戶不知道函數對形參做了什么手腳,在這種情況下進行重載是沒有意義的,所以規定不能重載!當指針或引用被引入時,用戶就會對函數的操作有了一定的了解,不再是透明的了,這時重載是有意義的,所以規定可以重載。
8 )什么情況下為 const 分配內存?
???????
以下是我想到的可能情況,當然,有的編譯器進行了優化,可能不分配內存。
??????? A
、作為非靜態的類成員時;
??????? B
、用于集合時;
??????? C
、被取地址時;
??????? D
、在 main 函數體內部通過函數來獲得值時;
??????? E
、 const class struct 有用戶定義的構造函數、析構函數或基類時;。
??????? F
、當 const 的長度比計算機字長還長時;
??????? G
、參數中的 const
??????? H
、使用了 extern 時。
???????
不知道還有沒有其他情況,歡迎高手指點:) ???????
9 )臨時變量到底是不是常量?
很多情況下,編譯器必須建立臨時對象。像其他任何對象一樣,它們需要存儲空間而且必須被構造和刪除。區別是我們從來看不到編譯器負責決定它們的去留以及它們存在的細節。對于 C++ 標準草案而言:臨時對象自動地成為常量。因為我們通常接觸不到臨時對象,不能使用與之相關的信息,所以告訴臨時對象做一些改變有可能會出錯。當然,這與編譯器有關,例如: vc6 vc7 都對此作了擴展,所以,用臨時對象做左值,編譯器并沒有報錯。
10 )與 static 搭配會不會有問題?
???????
假設有一個類:
??????? class A
??????? {
???????? public:
??????????????? ......
???????????? ?? static void f() const { ......}
??????????????? ......
???????? };
??
我們發現編譯器會報錯,因為在這種情況下 static 不能夠與 const 共存!
??
為什么呢?因為 static 沒有 this 指針,但是 const 修飾 this 指針,所以 ...
?
11 )如何修改常量?
??
有時候我們卻不得不對類內的數據進行修改,但是我們的接口卻被聲明了 const ,那該怎么處理呢?我對這個問題的看法如下:
??1
)標準用法: mutable
????????????? class A
????????????? {
?????????????? public:
????????????????????? A(int i=0):test(i)??????? { }
????????????????????? void SetValue(int i)const { test=i; }
?????????????? private:
????????????????????? mutable int test;?? file://這
里處理!
?????????????? }
;
2 )強制轉換: const_cast
?????????????? class A
?????????????? {
?????????????? public:
????????????????????? A(int i=0):test(i)??????? { }
????????????????????? void SetValue(int i)const
????????????????????? { const_cast <int>(test)=i; }//
這里處理!
?????????????? private:
????????????????????? int test;??
?????????????? }
3 )靈活的指針: int*
?????????????? class A
????????????? {
?????????????? public:
????????????????????? A(int i=0):test(i)??????? { }
????????????????????? void SetValue(int i)const
????????????????????? { *test=i; }
?????????????? private:
????????????????????? int* test;?? file://這
里處理!
?????????????? }

4
)未定義的處理
????????????? class A
????????????? {
?????????????? public:
????????????????????? A(int i=0):test(i)??????? { }
????????????????????? void SetValue(int i)const
????????????????????? { int *p=(int*)&test; *p=i; }//
這里處理!
?????????????? private:
????????????????????? int test;??
?????????????? }

???????????????
注意,這里雖然說可以這樣修改,但結果是未定義的,避免使用!
5
)內部處理: this 指針
????????????? class A
????????????? {
?????????????? public:
????????????????????? A(int i=0):test(i)??????? { }
????????????????????? void SetValue(int i)const
????????????????????? { ((A*)this)->test=i; }//
這里處理!
?????????????? private:
????????????????????? int test;??
?????????????? }
;
???????????? 6
)最另類的處理:空間布局
?????????????? class A
?????????????? {
??????????????? public:
????????????????????? A(int i=0):test(i),c('a') {? }
??????????????? private:
????????????????????? char c;
????????????????????? const int test;
??????????????? };
??????????????? int main()
??????????????? {
??????????????????? A a(3);
??????????????????? A* pa=&a;
??????????????????? char* p=(char*)pa;????
??????????????????? int*? pi=(int*)(p+4
); // 利用邊緣調整
??????????????????? *pi=5;???????????????? file://此
處改變了 test 的值!
??????????????????? return 0;
???????????????? }
雖然我給出了 6 中方法,但是我只是想說明如何更改,但出了第一種用法之外,另外 5 種用法,我們并不提倡,不要因為我這么寫了,你就這么用,否則,我真是要誤人子弟了:) ??
12 )最后我們來討論一下常量對象的動態創建。
??
既然編譯器可以動態初始化常量,就自然可以動態創建,例如:
??const int* pi=new const int(10);
這里要注意 2 點:
?1
const 對象必須被初始化!所以 (10) 是不能夠少的。
?2
new 返回的指針必須是 const 類型的。
?
那么我們可不可以動態創建一個數組呢?答案是否定的,因為 new 內置類型的數組,不能被初始化。
?
這里我們忽視了數組是類類型的,同樣對于類內部數組初始化我們也做出了這樣的忽視,因為這涉及到數組的問題,我們以后再討論。
?


??????????

Reference:

http://blog.csdn.net/boox/archive/2005/05/30/384509.aspx

http://www.bloghome.cn/posts/61287.html

http://blog.csdn.net/hwalk/archive/2006/05/20/746471.aspx

http://blog.csdn.net/hustli/archive/2003/06/30/19342.aspx

?

posted on 2007-10-06 01:43 旅途 閱讀(171) 評論(0)  編輯 收藏 引用 所屬分類: C/C++

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲欧美成人在线| 久久久亚洲国产天美传媒修理工| 亚洲国产精品免费| 亚洲新中文字幕| 亚洲第一区中文99精品| 亚洲精品一区二区网址| 午夜伦理片一区| 国产精品jizz在线观看美国 | 久热精品视频在线观看| av成人免费| 国产精品99久久久久久www| 伊伊综合在线| 99视频精品全国免费| 亚洲图片欧洲图片av| 在线综合亚洲| 久久亚洲精品伦理| 欧美成人国产va精品日本一级| 国产色婷婷国产综合在线理论片a| 欧美高清一区| 欧美搞黄网站| 性欧美在线看片a免费观看| 欧美亚洲成人网| 亚洲欧美日韩国产中文在线| 亚洲一品av免费观看| 欧美视频在线免费看| 亚洲视频香蕉人妖| 亚洲一区二区伦理| 国产日韩欧美视频在线| 久久久久久穴| 美女脱光内衣内裤视频久久影院| 亚洲高清色综合| 亚洲美洲欧洲综合国产一区| 国产精品久久久久一区| 久久精品一区二区三区中文字幕| 久久久国产精品一区| 亚洲精品中文字| 亚洲影院色无极综合| 中国成人黄色视屏| 欧美激情综合亚洲一二区| 亚洲一本视频| 久久精品国产精品| 性久久久久久久| 国精品一区二区三区| 欧美福利专区| 国产精品久久久久久久午夜片| 美女国内精品自产拍在线播放| 欧美国产日韩一区二区| 欧美专区在线观看| 欧美伦理91| 午夜激情久久久| 男女激情视频一区| 亚洲免费在线播放| 欧美成人亚洲成人日韩成人| 亚洲宅男天堂在线观看无病毒| 久久爱91午夜羞羞| 中文无字幕一区二区三区| 久久精品欧美日韩| 美日韩精品视频| 一本色道久久88精品综合| 亚洲一区二区精品在线| 亚洲人精品午夜在线观看| 夜夜夜久久久| 亚洲第一区在线| 亚洲欧美中文另类| 亚洲人成在线观看一区二区| 久久国产一区二区| 午夜精品一区二区三区在线播放 | 亚洲视频一区二区| 欧美在线视频观看| 亚洲午夜一区| 欧美伦理91| 欧美激情精品久久久久| 国产一级精品aaaaa看| 亚洲天堂免费在线观看视频| 一本色道久久综合亚洲精品不卡 | 免费看精品久久片| 国产欧美日韩不卡免费| 在线视频亚洲一区| 国产精品日本一区二区 | 久久久久久婷| 亚洲欧美一区二区视频| 欧美日韩国产精品一卡| 欧美激情精品久久久久久免费印度| 国产一区二区三区久久久| 亚洲自拍都市欧美小说| 在线一区欧美| 欧美揉bbbbb揉bbbbb| 9l国产精品久久久久麻豆| 一区二区三区免费网站| 欧美日韩一区二区三区免费看 | 欧美一区二区视频在线观看| 午夜视频在线观看一区二区| 欧美日韩在线播放三区四区| 日韩亚洲欧美成人一区| 亚洲午夜未删减在线观看| 欧美日韩精品免费观看视频完整| 亚洲激情精品| 日韩视频免费观看高清在线视频 | 欧美大片va欧美在线播放| 亚洲第一天堂av| 欧美在线视频一区二区| 久久久久高清| 在线观看中文字幕亚洲| 免费在线看成人av| 亚洲日本免费电影| 亚洲欧美久久久| 久久久久国色av免费观看性色| 欧美亚洲在线视频| 欧美日韩国产小视频| 亚洲美女电影在线| 欧美成人激情视频| 一区二区视频在线观看| 久久人人爽人人爽| 亚洲国产成人久久综合一区| 日韩午夜免费视频| 国产精品久久久久久久浪潮网站 | 欧美激情小视频| 一区二区久久久久久| 国产精品资源| 久久亚洲欧美| 一本色道久久88综合日韩精品 | 亚洲欧美在线观看| 亚洲承认在线| 亚洲一区高清| 久久国产精品久久久久久电车| 国产日韩精品一区二区| 久久久久国色av免费观看性色| 欧美顶级少妇做爰| 99re这里只有精品6| 国产精品视频99| 欧美在线一区二区| 亚洲国产精品一区在线观看不卡 | 99国产精品国产精品久久| 女仆av观看一区| 久久黄色级2电影| 麻豆精品网站| 国产欧美精品一区二区色综合 | 另类亚洲自拍| 久久综合影视| 99热在这里有精品免费| 久久久久久久久蜜桃| 欧美视频免费在线观看| 亚洲高清色综合| 亚洲精品久久久久中文字幕欢迎你 | 久久精品水蜜桃av综合天堂| 久久美女性网| 牛夜精品久久久久久久99黑人 | 久久深夜福利| 国产精品日韩欧美大师| 国产情人节一区| 亚洲乱码一区二区| 欧美1区2区| 国产精品免费视频xxxx| 亚洲国产va精品久久久不卡综合| 日韩一级裸体免费视频| 一区二区欧美亚洲| 亚洲国产精品一区二区第一页| 亚洲一区二区在线| 狠色狠色综合久久| 日韩亚洲欧美一区二区三区| 欧美日韩成人一区二区| 国产欧美一区二区在线观看| 久久九九有精品国产23| 欧美在线日韩在线| 亚洲欧美国产va在线影院| 午夜激情久久久| 欧美成人有码| 欧美一级成年大片在线观看| 亚洲另类黄色| 亚洲国产日韩欧美在线99| 鲁大师成人一区二区三区| 亚洲少妇中出一区| 亚洲精品在线观看免费| 最新成人av在线| 亚洲二区在线| 一区在线播放视频| 一区二区三区自拍| 精品69视频一区二区三区| 午夜视频在线观看一区二区三区| 午夜一区二区三区在线观看| 亚洲自拍另类| 亚洲六月丁香色婷婷综合久久| 免费成人性网站| 女主播福利一区| 免费成人av资源网| 欧美v国产在线一区二区三区| 另类春色校园亚洲| 欧美高清视频一区二区| 欧美日韩国产成人高清视频| 欧美体内she精视频| 欧美性淫爽ww久久久久无| 国产精品一区二区久久国产| 国产欧美一区二区色老头| 国内久久精品视频| 亚洲精品乱码久久久久久蜜桃91| 亚洲精品一区二区三区99| 亚洲一区二区影院| 久久久国产午夜精品| 欧美h视频在线| 亚洲精品国产视频|