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

BillyYu

Why C++? ( Both versions)---轉載自CSDN

劉未鵬(pongba) /文

waterwalk /譯

C++的羅浮宮(http://blog.csdn.net/pongba)

首先非常感謝waterwalk的辛勤翻譯:-) waterwalk把翻譯回貼在原文的下面了,為
了方便閱讀我提取出來編輯以后重發一個帖子。這篇文章原本是想對最近C/C++爭論
系統的整理一下一些思考的,但由于一開始的時候用英文寫了兩段,后來就干脆都用
英文了,造成很多人閱讀的麻煩,在此抱歉。不過好在waterwalk翻譯了整篇文章,
于是單獨貼在這里:-)

問題

為什么用C++呢? 在你皺著眉頭離開之前,試著回答這個簡單的問題。效率,是么
?人人都知道這個。但情況是,當一個人開始討論編程語言或與其相關的話題時,他
必須要非常明確而有針對性。為什么呢?我來問你另一個問題:如果效率是人們使用
C++的唯一理由,那么為啥不直接用C呢?C被認為比C++效率更高(嗯嗯,我知道C沒
有比C++的效率高多少,所以這里別誤解我的意思,因為即使它們二者效率相同,剛
才的問題依然存在)。

迷思

我知道你又要說“更好的抽象機制”了,因為畢竟C++是要設計成一個更好的C的。
C++沒有犧牲效率,同時又添加了這么多高級特性。但問題是,“開發者們真的需要
這些高級特性么?”。畢竟我們一直聽人講KISS之類的東西。我們也都聽到有聲稱C
比C++更KISS所以我們要用C云云。這種持續不斷的爭論將C與C++之間的比較變成了一
個大大的迷題(或者說是混亂)。令人驚訝的是,貌似的確有很多人更加傾向于用C
,最大的理由就是C++實在是太難用對了。甚至Linus也這么想。

這種現象最大的影響就是當人們在C和C++之間權衡時,使人們傾向于使用C。而且
一旦人們開始用C,他們很快就適應并滿足了(其實,在任何語言乃至任何人類活動
中都有此現象,C++亦然,比如常常聽到有人說“XX語言我用了這么多年,一直用得
好好的”,照這種說法任何圖靈完備的語言還不都是能用來編程?)。于是即使他們
還沒有試試C++,或者他們還沒成為好的C++程序員時,他們就開始聲稱C比C++更好了
。然而其實呢,真實的答案往往總是取決于實際情況的。

我說過“取決于實際情況”了么?那到底實際情況是什么呢?顯然,有些領域C是
更好的選擇。例如設備驅動開發就不需要那些OOP/GP技巧。而只是簡單的處理數據,
真正重要的是程序員確切地知道系統是如何運轉的,以及他們正在做什么。那么寫操
作系統呢?我本人并沒有參與任何操作系統的開發,但我讀過不少操作系統代碼(大
多是unix的)。我的感覺是操作系統很大一部分也不需要OOP/GP。

但是,這就表示在所有效率重要的領域,C都是比C++更好的選擇么?未必。

答案

讓我們一個一個來分析。

首先,當人們關注效率時,有2種效率——時間效率(例如OS,運行時庫,實時應
用程序,high-demanding的系統)和空間效率(例如各種嵌入式系統)。但是,這樣
的分類并不能幫我們決定用C還是C++,因為C和C++的時空效率都很高。真正影響選擇
語言的因素是業務邏輯(這里的“業務邏輯”并非表示“企業應用業務”)。例如,
使用OOP/GP來表達邏輯(或者說代碼的結構)好呢,還是就只用數據和過程好呢?

據此觀點,我們可以把應用程序大致分為兩類(當然前提是關注的是C/C++而不是
java/C#/ruby/erlang等等):底層應用程序和高層應用程序。這里底層是指像OB/
OO和GP沒啥用處的地方, 其余歸到高層。顯然,在所有C/C++應用的領域(這些領
域需要C/C++的效率),屬于高層的應用有很多(可以看看Bjarne Stroustrup在他主
頁上的列表)。在這些領域中,抽象至少是和效率一樣重要的。而這些正是C++適用
的場合。

等等還有。即使在程序員不需要高級抽象的領域,也不是就絕對用不到C++的。為
啥呢?僅僅是因為你的代碼中沒有用類或模板并不意味著不能用以類或模板實現的庫
。因為有如此眾多方便的C++庫(還有即將到來的tr1/tr2),我覺得有充分的理由在
這些領域中使用C++——你可以在編碼時僅使用C++中的C核心(以任何你喜歡的方式
來KISS),同時還能用強大的C++庫(比如STL容器、算法和tr1/tr2的組件)。

最后,我認為人們還常常忽略了一點——有時KISS也是建立在抽象上的。我覺得M
atthew Wilson在他新書《Extended STL,卷1》的序言中對此做了很好的闡釋。他
寫了2段代碼,一段用C,另一段用C++:

 

// in C

DIR
*  dir = opendir(".");

if(NULL != dir)

{

  struct dirent
*  de;

  
for(; NULL != (de = readdir(dir)); )

  {

    struct stat st;

    
if0 == stat(de->d_name, &st) &&

        S_IFREG 
== (st.st_mode & S_IFMT))

    {

      remove(de
->d_name);

    }

  }

  closedir(dir);

}



// in C++

readdir_sequence entries(
".", readdir_sequence::files);



std::for_each(entries.begin(), entries.end(), ::remove);

 

而在C++09里面更簡單:

// in C++09

std::for_each(readdir_sequence(
".", readdir_sequence::files), ::remove)
;


也就是說,我認為即使一個人在自己的代碼里不需要類或模版,他也有理由用C++
,因為他用的那些方便的C++庫用到了類和模板。如果一個高效的容器(或智能指針
)能把你從無聊的手動內存管理中解放出來,為啥還要用那原始的malloc/free呢?
如果一個更好的string類(我可沒說std::string,地球人都知道那個不是C++中能做
出的最好的string類)或正則表達式類能把你從一坨一坨的、你看都不想看的處理字
符串的代碼中解脫出來,那么為啥還要手動去做這些事呢?如果一個 "transform"(
或"for_each")能夠用一行代碼把事情漂亮搞定,為啥還要手寫一個for循環呢?如
果高階函數能滿足你的需要,那么為啥還要用笨拙的替代方法呢?(OK,我知道,最
后兩個需要C++加入lambda支持才真正擺脫雞肋的罵名——這正是C++0x的任務嘛)

 總之,我認為KISS并不等同于“原始”;KISS意味著用最適合的工具來做事情,這
里“最合適”的意思是工具能夠幫你以盡量直接簡潔的方式來表達思想,同時又不降
低代碼的可讀性,另外還保持代碼容易理解。

 真正的問題

人們可能會說,相較于被正確使用而言,C++(遠遠)更容易被錯誤使用。而相比
而言,C程序的復雜性更容易管理和控制。在C++中,一個普通程序員很可能會寫出一
堆高度耦合的類,很快情況就變得一團糟。但這個其實是另外一個問題。在另一方面
,這種事情也很可能發生在任何一門面向對象語言中,因為總是有程序員在還沒弄懂
什么是HAS-A和IS-A之前,就敢于在類上再寫類,疊床架屋的一層一層摞上去。他們
學會了在一門特定的語言中如何定義類,如何繼承類的語法,然后他們就認為自己已
經掌握了OOP的精髓了。另一方面,這一問題在C++中更為嚴重,因為C++有如此眾多
的偶然復雜性在阻礙設計;而且C++又是如此靈活,很多問題在C++中都有好幾種解決
辦法(想想那么多的GUI庫吧),于是在這些選擇中進行權衡本身就成了一個困難。
C++中的非本質復雜性是其歷史包袱使然,而C++0x正是要努力消除這些非本質復雜
性(在這方面C++0x的工作的確做得很不錯)。對于設計來說,靈活性不是個壞事情
——可以幫助好的設計者作出好的設計。如果有人抱怨說這個太費腦細胞了,那可能
是這個設計者本身的問題,而不能怪語言。可能就不該讓他來作設計。如果你擔心C
++的高級特性會把你的同事引入歧途,把項目搞砸,那你也許應該制定一份編碼標
準并嚴格推行(或者你也可以遵循C++社群這些年積攢下來的智慧,或者在必要時,
只使用C++中的C或C with class那部分),而不是因為有風險就躲開C++(其實這些
風險可以通過一些政策來避免的),因為那樣的話,你就沒法用那些C++的庫了。

 另一方面,其實一個更為重要的問題是一個心理學問題——如果一門語言中存在某
個奇異的特性或旮旯,那么遲早總會有人發現的,總會有人為之吸引的,然后就使人
們從真正有用的事情中分心出來(這有點像Murphy法則),更不用說那些有可能對真
正問題帶來(在某種程度上)漂亮的解決方案的語言旮旯了。人們本性上就容易受到
稀有資源的誘惑。奇技淫巧是稀有資源,于是奇技淫巧便容易吸引人們的注意力,更
別說掌握一個技巧還能夠讓那人在他那圈子里感覺非常牛了。退一萬步,你會發現,
即使是一個廢柴技巧也能引起人們足夠的興趣來。

 C++中有多少陰暗角落呢?C++中又有多少技巧呢?總的來說,C++中,有多少非本
質復雜性呢?(懂一定C++的人一定知道我在說什么)

 平心而論,近年來(現代C++中)發現的大多數技巧或(如果你愿意稱之為)技術
實際上都是由實際需求驅動的,尤其是需要實現高度靈活而又普遍適用(generic)
的類庫 (例如boost中的那些玩意)。而這些技巧也的確(在某種程度上)提供了對
實際問題的漂亮解決方案。讓我們來這么想一下,如果你處于一個兩難境地:要么用
那些奇技淫巧來做點很有用的東西,要么不做這樣其他人也就沒得用。你會如何選擇
呢?我知道boost的英雄們選擇了前者——不管多么困難多么變態多么齷齪,把它做
出來!

 但所有這些爭論都不能改變一個事實:我們理應享有一個語言,能夠讓我們用代碼
清晰的表達思想。以boost.function/boost.bind/boost.tuple為例,variadic tem
plates可以大大簡化這幾個庫的實現(減至幾乎是原先1/10的代碼行數),同時代
碼也(遠遠)更加簡潔易懂。Auto,initializer-list,rvalue-reference,templ
ate-aliasing,strong-typed enums,delegating-constructors,constexpr,al
ignments,inheriting-constructors,等等等等,所有這些C++0x的特性,都有一
個共同目的——消除語言中多方面的非本質復雜性或語言中的尷尬之處。

 正如Bjarne Stroustrup所說,很顯然C++太過復雜了,很顯然人們被嚇壞了,并且
時不時就不用C++了。但“人們需要相對復雜的語言去解決絕對復雜的問 題”。我們
不能通過減少語言特性而使其更加強大。復雜的特性就連模板甚至多繼承這樣的也是
有用的——如果你正好需要它們,而且如果你極其小心使用,不要搬起石頭砸自己的
腳的話。其實在所有C++的復雜性當中,真正阻礙了我們的是“非本質復雜性”(有
人稱之為“尷尬之處”),而不是語言所支持的編程范式(其實也就3個而已)。而
這也正是我們應該擁抱C++0x的重要原因,因為C++0x正是要消除那些長期存在的非本
質復雜性,同時也使得那些奇技淫巧不再必要(很顯然,目前這些技巧堆積如山,翻
翻那些個C++的書籍,或者瞅瞅boost庫,你就知道我在說啥了),這樣我們就能夠直
觀清晰的表達思想。

 結論

C++難用,更難用對。所以當你決定用它時,要小心,要時刻牢記自己的需求,所
要達到的目的。這里有一個簡單的指南:

 我們需要高效率么?

 如果需要,那么我們需要抽象么(請仔細思考這一點,因為很難評估使用C++高級特性是否能夠抵
消誤用這些機制的風險;正確的回答取決于程序員的水平有多高,遵循哪種編碼標準
以及編碼標準執行得如何,等等)?

 如果是,那么用C++吧。如果不是,那么,

 我們需要用C++庫來簡化開發么?

 如果是,那就用C++吧。但同時必須時刻牢記你在做什么——如果你的代碼不需要
那些“漂亮的”抽象,那就別試圖使用以免陷入其中。別只是因為你在.cpp文件中寫
代碼以及你用的是C++編譯器就要用類啊、模板啊這些東西。

 如果不是,那就用C,不過你又會想為啥不僅僅使用C++中屬于C的那部分核心呢?
還是老原因:人們很容易就陷入到語言的“漂亮”特性中去了,即使他們還不知道這
些特性是否有用。我都記不清有多少次自己寫了一大堆的類和繼承,到最后反倒要問
自己“要這么些個類和繼承做什么呀?”。所以,如果你能堅持只用C++中C或C wit
h class的那部分,并遵循“讓簡單的事情保持簡單”的理念;或者你需要把C代碼
遷移到C++中來的話,那么就用C++吧,但要十分小心。另一方面,如果你既不需要抽
象機制,也不需要C++庫,因為事情非常簡單,不需要方便的組件例如容器和字符串
,或者你已認定C++能夠給項目帶來的好處微乎其微,不值得為之冒風險,或者干脆
就沒那么多人能用好C++,那么可能你還是只用C的好。

 底線是:讓簡單的事情保持簡單(但同時也請記住:簡單性可以通過使用高級庫來
獲得);必要時才使用抽象(切記不可濫用;遵循好的設計方法和最佳實踐)。

原文:
The Problem

So, why C++? Before you frown and turn away. Just try to answer this simple question.

Efficiency, right? Everybody knows the answer. But as it turned out, when discussing a programming language or everything related to one, one should be very specific. Now why’s that? Let me ask you another question: if efficiency is the only reason people use C++, then why don’t they just use C? C is admittedly more efficient than C++ (yeah, yeah, I know it has been proved that C isn’t to any significant extent more efficient than C++, so don’t get me wrong here, because even if they are equally efficient, the problem still exists).

The Myth

I know you are going to say “better abstraction mechanism”, because after all C++ is designed to be a better C, one that has uncompromised efficiency and yet at the same time has all those fancy high-level features. But then the problem comes down to “does it really matter if the developers need those fancy features?”  I mean, after all we all have been hearing voices about KISS and stuff, and we all have heard about the claim that, compared to C++, C is more KISS so we should use C. This unstoppable argument has turned the comparison between C and C++ into a big myth (or maybe a mess). And surprisingly, it seems that many people do incline to C, the reason mostly being that C++ is so hard to use right. Even Linus thinks so, too.

The real serious impact of this phenomenon is that it drives more people to C when they’re weighing their options, be them C and C++; and once they start using C, they will soon get satisfied and comfortable with what suffices, experiencing what is called “satisfaction”. This is when they will come out and claim that C actually is a better choice than C++ even though they didn’t actually try to use C++ or they aren’t adequately good C++ programmers at all. The real answer, however, almost always begins with “it depends”.

So, did I say “it depends”? On what? Obviously there’re some areas where C is a better choice than C++. For instance, device driver development is usually something that doesn’t need fancy OOP/GP techniques. It’s just simple data manipulation; what really matters is the programmers know exactly how the system works, and what they’re doing. Now what about OS development? I’m not a guy who’s been involved in any kind of OS development myself, but having read a fair amount of OS code (Unix mostly), I’ve come to feel that there’s a significant part of the OS development that doesn’t need OOP/GP either.


However, does that mean that, in all those areas where efficiency matters, C is a better choice than C++? Not really.

The Answer

Let’s do this case by case.

First of all, when people are concerned about efficiency, there’re really two kinds of efficiency – time efficiency (e.g. OS, runtime, real-time applications, high-demanding systems) and space efficiency (e.g. all sorts of embedded systems). However, this categorization doesn’t really help us determine whether we should use C or C++, because C and C++ are both extremely efficient as to both time and space. What really affects our language choice (between C and C++, of course) is the business logic (here by “business”, I don’t mean the “enterprise application business”). For example, is it better to use OOP/GP to express the logic or is it better off being kept pretty much just about data and procedures.

From this point of view, we can vaguely divide applications into two categories (of course, with the premise that what we’re concerned with is C/C++, not java/c#/ruby/erlang etc.): low-level applications and high-level applications, where low-level applications means the ones where fancy abstractions such as OB/OOP and GP are pretty much of no use, and high-level means all the rest. Now, obviously, of all the areas where C/C++ is used (because of their high-efficiency), there’re a significant number of “high-level” applications (see those listed on Bjarne Stroustrup’s homepage), where abstraction is just as important as, if not more important than efficiency. And those are precisely the places where C++ is used and useful in a unique sense, and where C++ is a better choice than C.

Wait, there’s more. As it turns out, even in those areas where programmers don’t use high-level abstractions in their code per se, there might be a reason they should use C++, too. Why’s that? Just because your code don’t use class or templates doesn’t mean it doesn’t use a library that does. Considering the availability of all the handy C++ library facilities (with tr1/tr2 coming soon), I think there’s a pretty strong reason to use C++ in these cases - you can stick to the C core of C++ when coding (KISS in any way you want), and at the same time you’ve got some awesome C++ libraries at your disposal (e.g. STL containers and algorithms, tr1/tr2 components, etc.). And finally, there’s this one thing that’s always ignored by many people – sometimes KISS relies on abstractions. I think Matthew Wilson made a crystal clear point about this in the prologue of his new book “Extended STL, Vol 1”, where he laid down two blocks of code, one written in C and one in C++:

 

// in C

DIR
*  dir = opendir(".");

if(NULL != dir)

{

  struct dirent
*  de;

  
for(; NULL != (de = readdir(dir)); )

  {

    struct stat st;

    
if0 == stat(de->d_name, &st) &&

        S_IFREG 
== (st.st_mode & S_IFMT))

    {

      remove(de
->d_name);

    }

  }

  closedir(dir);

}

// in C++

readdir_sequence entries(
".", readdir_sequence::files);

std::for_each(entries.begin(), entries.end(), ::remove);

And it’s even simpler in C++09:

// in C++09

std::for_each(readdir_sequence(
".", readdir_sequence::files), ::remove);

I think this is exactly the reason why one should use C++ even in those cases where he doesn’t really need class or templates in his own code – the handy C++ libraries he will find very useful does. Similarly, if an efficient container (or a smart pointer) will save you from all the boring job of manual manipulation of memory, then what’s the point of using the primitive malloc/free? If a better string class (I’m not talking about std::string; everybody knows it’s not the best C++ can do) or regex class  can relieve you of all the cluttered string-manipulation code you don’t even want to look at, then what’s the point of doing it manually. If a ‘transform’ (or a ‘for_each’) can do your job in one line so succinctly and clearly (and I know, of course, C++ need lambda function support for those – that’s what C++0x is for), then what’s the point of hand-written for-loops? If high-order function is really what you need, then what’s the point of using awkward workarounds to approach the same deal?

KISS doesn’t mean “primitive”; KISS means using the most suitable tool for your job, where “most suitable” means the tool you use should help you express your mind as straight (and succinct) as possible, as long as it doesn’t compromise the readability and understandability of the code.

The Real Problem

People might say that C++ is much more easily misused than properly-used, and C, on the other hand, is always more manageable and controllable as to complexity. In C++, an average programmer might come up with a whole bunch of highly coupled classes that degenerates fast into a big mess. But this is actually a separate issue. On the one hand, it can pretty much occur in any object oriented language. There’re always programmers who dare to write classes on top of classes even before they have any idea what HAS-A is and what IS-A is; they learn all the syntax of defining a class and inheriting one from another and they thought they’ve grasped the essence of OOP. On the other hand, the reason it appears to be more serious in C++ is because C++ has so many accidental complexities that impede the design, and because C++ is so flexible that pretty much every problem in C++ has several alternative solutions (thinking of all the GUI libraries) so that weighing all the options becomes a hard job itself. The accidental complexities are a historical baggage that C++0x is trying so hard to (and hopefully will) get rid of; the flexibility with respect to design isn’t actually a bad thing if you think about it - it helps good designers make good designs; and if someone blame them for hurting his brain then maybe it’s his problem, not the language’s; maybe he shouldn’t be the one to make a design. And if you’re so worried that your fellow C++ coders will be enticed by fancy high-level features and that your project will eventually get screwed, then maybe what you should do is setting up a coding standard and enforce it (or you can just follow the collective wisdom, or stick to the C core or C with class part of C++ if necessary), not flinching away just because there’re risks (risks that can be avoided by policies), because then you will not be able to access all the C++ libraries anymore, mind you.

On the other hand, there’s this more important psychological problem – if there’s a bizarreness in a language, then eventually someone will find it and people will be attracted by it, and it will draw energy from the main people effort of doing something really useful (It’s kind of like the Murphy's Law), let alone the ones that can lead to an (on some level) elegant solution to a real problem. People are inherently attracted by scarce resources. Corollary: Tricks and bizarrenesses are scarce resources, so they draw people’s attention, not to mention the fact that mastering a trick makes one feel special in the herd. The bottom line is, even useless tricks draw people’s attention so heavily.

How many black corners are there in C++? How many tricks are there in C++? All in all, how many accidental complexities are there in C++?

To be fair, most of the tricks and (you might say) techniques that have been discovered in recent years (i.e. modern C++) are driven by real needs, particularly the needs to implement highly flexible and generic library components (thinking of all the components in boost). And they did lead to (on some level) elegant solutions to real problems. Think about it this way: if you’re put in a place where either you have to use tricks to implement something really useful or you don’t implement it so other people won’t have the benefit of using it. What would you choose? I know that the boost heroes chose the former – implementing them, no matter how hard and tricky and cumbersome the implementation is.

But all those arguments don’t change the fact that we deserve to have a language that supports a clean way to express our minds in code. Take boost.function/boost.bind/boost.tuple for examples, variadic templates will tremendously simplify (by reducing the LOC to nearly 1/10 of the original) the implementation of the three (and many, many more to come) libraries, and the code will become succinct and as simple as possible, too. Auto, initializer-list, rvalue-reference, template-aliasing, strong-typed enums, delegating-constructors, constexpr, alignments, inheriting-constructors, etc; all those C++0x features, they all have one goal – eliminating the various accidental complexities or embarrassments of the language.

As Bjarne Stroustrup said, obviously C++ is too complicated; obviously people get scared and sometimes turn away. But “people need relatively complex language to deal with absolutely complex problems”. We can’t make a language more powerful by taking features away from it. Complex features like templates and even multiple-inheritance can be useful if they’re exactly what you need, you just have to use them very carefully and by necessity so that you don’t shoot yourself in the foot. Of all the complexities in C++, the ones that really get in our way are the accidental complexities (someone might call them “embarrassments”), not the paradigms the language supports (there’re only three). And that’s a very important reason why we should embrace C++0x, because it aims at eliminating the long standing accidental complexities C++ had and make obsolete all the arcane tricks (there’s absolutely huge amount of them out there; check all the C++ books and maybe the boost library and you’ll know what I’m talking about) so that we can express our mind clearly and directly.

 
The Conclusion
C++ is hard, and even harder to use correctly. So when you decide to use it, be careful, always know where you are and what you really want. Here’s a simple guideline:

Do we need to be efficient?

If so, then

Do we need abstractions in our code (think very carefully on this one, because it’s very hard to estimate whether the benefit of using the high-level features of C++ outweighs the risk of using them incorrectly; the proper answer depends on how well trained your programmers are, what coding standard you follow and how well it’s enforced, etc.)?

If so, then use C++. Otherwise,

Do we need good C++ libraries to ease our job?

If so, then use C++, but meanwhile always remember what you are doing – if your code doesn’t really need all the fancy abstractions, then try not to get sucked into them; don’t use class or templates just because you’re writing code in a .cpp file and using a C++ compiler.

Otherwise, use C, but then you might wonder why not just use the C core of C++. The same reason as always: people get easily sucked into fancy language features even when they don’t really know if they’re going to help – I can’t tell you how many times I wrote a bunch of classes only to find out “what the heck are these classes for?”. So, if you can stick to the C core or C with class part of C++ and keep simple things simple, or if your code needs a migration path from C to C++, use C++ then, but be very careful. On the other hand, if you need neither abstraction mechanisms in your code nor quality C++ libraries because what you’re doing is so simple that you don’t even need convenient components like containers or strings, or you decide that the benefit C++ can bring you in your project is minor to an extent that it’s not even worth taking the risk, or you just simple don’t have enough people that can use C++ in a proper way, then maybe you should stick to C.

The bottom line: keep simple things simple (but remember that simplicity can be achieved by using high-level libraries); use abstractions when necessary (and even then, make spare use of it; follow good design principles and established good practices).

posted on 2007-09-15 10:20 志華 閱讀(237) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


<2007年9月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

導航

統計

常用鏈接

留言簿(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>
            一区二区三区四区五区视频| 一区二区三区导航| 久久精品国产亚洲一区二区| 欧美一区二区高清在线观看| 国产亚洲va综合人人澡精品| 久久精品成人一区二区三区 | 在线播放日韩| 欧美激情国产日韩| 欧美日韩1区| 欧美一级视频免费在线观看| 亚洲欧美久久久久一区二区三区| 韩国精品在线观看| 亚洲电影在线播放| 欧美日韩不卡视频| 性欧美8khd高清极品| 久久精品麻豆| 一区二区三区四区五区视频| 亚洲欧美日本另类| 最新成人在线| 亚洲一区二区三区精品在线观看 | 久久免费精品视频| 夜夜嗨av色综合久久久综合网| 一区二区三区蜜桃网| 国产亚洲一区二区三区在线观看| 亚洲电影在线| 国产日本欧美一区二区| 亚洲国产精品一区二区久| 国产精品h在线观看| 毛片一区二区三区| 欧美日韩三级电影在线| 鲁大师影院一区二区三区| 欧美日韩精品一区二区三区| 久久一区二区精品| 欧美视频在线观看免费| 免费亚洲电影在线观看| 国产精品久久一区主播| 亚洲黑丝一区二区| 国内伊人久久久久久网站视频| 日韩天堂在线观看| 亚洲经典视频在线观看| 久久aⅴ乱码一区二区三区| 亚洲天堂第二页| 欧美aaa级| 久久五月激情| 国产精一区二区三区| 亚洲精品乱码视频| 亚洲经典一区| 久久av一区二区三区漫画| 亚洲免费伊人电影在线观看av| 美女图片一区二区| 久久夜色精品国产欧美乱| 国产精品美女视频网站| 99re这里只有精品6| 亚洲国产精品久久久久婷婷老年| 欧美在线播放一区| 欧美在线关看| 国产日韩欧美在线观看| 亚洲一区三区电影在线观看| 亚洲一区免费在线观看| 欧美片第一页| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲国产91| 久久久精品日韩欧美| 久久一区二区精品| 国产在线高清精品| 欧美在线欧美在线| 久久精品一区四区| 国产综合欧美| 久久综合亚洲社区| 欧美国产一区二区在线观看| 亚洲国产精品黑人久久久| 欧美a级大片| 亚洲激情网站免费观看| 亚洲伦理在线免费看| 欧美日韩精品一区视频| 国产精品99久久不卡二区| 午夜视频久久久| 国产日韩精品一区二区浪潮av| 午夜精品久久久久久久蜜桃app | 亚洲一区二区三区中文字幕| 午夜宅男欧美| 韩国在线视频一区| 免费人成精品欧美精品| 亚洲精品国产欧美| 小辣椒精品导航| 精品成人在线观看| 欧美国产精品久久| 亚洲午夜精品一区二区| 久久精品日产第一区二区| 在线观看视频亚洲| 欧美精品久久久久久| 中文日韩在线视频| 欧美自拍偷拍| 亚洲激情图片小说视频| 国产精品高潮呻吟视频| 羞羞视频在线观看欧美| 欧美黄色大片网站| 午夜宅男久久久| 在线看不卡av| 国产精品分类| 久久久久久久999精品视频| 亚洲国产综合在线| 久久精品国产一区二区三区免费看 | 免费成人网www| 一区二区三区偷拍| 欧美99在线视频观看| 亚洲性图久久| 亚洲成人资源网| 国产精品蜜臀在线观看| 免费成人性网站| 先锋亚洲精品| 亚洲毛片av| 欧美大片一区| 久久精品一二三| 一区二区三区回区在观看免费视频| 国产综合色在线| 欧美色欧美亚洲另类七区| 久久天堂成人| 欧美一区二区三区电影在线观看| 亚洲精品美女在线| 欧美3dxxxxhd| 久久免费偷拍视频| 欧美在线国产精品| 亚洲在线视频观看| 亚洲巨乳在线| 伊人精品在线| 好看的av在线不卡观看| 国产欧美日韩亚洲精品| 国产精品va| 欧美视频在线观看一区| 欧美成人精品一区| 美女黄网久久| 毛片一区二区| 久久一区二区三区四区五区| 欧美一区影院| 欧美在线啊v| 欧美在线视频a| 欧美一区在线看| 欧美亚洲日本一区| 午夜精品在线视频| 亚洲欧美日韩国产综合精品二区| 99国产精品久久| 这里只有精品在线播放| 这里只有精品电影| 亚洲视频在线免费观看| 亚洲天堂网在线观看| 亚洲一级二级| 亚洲欧美久久| 久久精品99无色码中文字幕| 欧美一级二区| 久久久综合免费视频| 嫩草伊人久久精品少妇av杨幂| 久久综合伊人| 欧美另类高清视频在线| 欧美日韩一区高清| 国产伦精品一区二区三区免费 | 激情成人综合| 在线观看一区| 亚洲美女一区| 亚洲与欧洲av电影| 久久成人综合网| 久久久另类综合| 免费亚洲电影在线| 亚洲高清不卡av| 一区二区三区精品视频在线观看| 中文在线不卡| 欧美一级理论性理论a| 久久一综合视频| 欧美久久99| 国产日韩精品一区二区三区在线| 精品9999| 一区二区三区欧美亚洲| 欧美一区二区日韩| 欧美风情在线| 亚洲少妇最新在线视频| 久久九九国产精品怡红院| 欧美国产一区二区三区激情无套| 欧美日一区二区三区在线观看国产免| 国产精品无码永久免费888| 亚洲第一伊人| 亚洲在线成人| 欧美激情视频一区二区三区免费| 999亚洲国产精| 久久―日本道色综合久久| 欧美日韩一区二区三区| 伊人一区二区三区久久精品| 亚洲视频视频在线| 欧美不卡视频一区发布| 亚洲尤物在线| 欧美精品午夜视频| 伊人久久大香线蕉av超碰演员| 一区二区不卡在线视频 午夜欧美不卡在 | 麻豆成人在线播放| 国产九区一区在线| 亚洲精品久久久久久下一站 | 在线播放一区| 欧美在线观看天堂一区二区三区| 亚洲国产精彩中文乱码av在线播放| 亚洲欧美日本伦理| 欧美日韩色婷婷|