日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Boost - 序列化 (Serialization)

發(fā)布時間:2023/12/9 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Boost - 序列化 (Serialization) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

From: https://blog.csdn.net/zj510/article/details/8105408

程序開發(fā)中,序列化是經(jīng)常需要用到的。像一些相對高級語言,比如JAVA, C#都已經(jīng)很好的支持了序列化,那么C++呢?當然一個比較好的選擇就是用Boost,這個號稱C++準標準庫的東西。

什么時候需要序列化呢?舉個例子,我們定義了一個class,比如:

??? class CCar
??? {
??? public:
?? ??? ?void SetName(std::string& strName){m_strName = strName;}
?? ??? ?std::string GetName() const{return m_strName;}
??? private:
?? ??? ?std::string m_strName;
??? };


然后我們想把這個類的一個對象保存到文件中或者通過網(wǎng)絡發(fā)出去,怎么辦呢?答案就是:把這個對象序列化,然后我們可以得到一個二進制字節(jié)流,或者XML格式表示等等。

這樣我們就可以保存這個對象到文件中或者通過網(wǎng)絡發(fā)出去了。把序列化的數(shù)據(jù)進行反序列化,就可以得到一個CCar對象了。

Boost已經(jīng)很好的支持了序列化這個東西,很好很強大。

Boost網(wǎng)站上有介紹: http://www.boost.org/doc/libs/1_51_0/libs/serialization/doc/index.html

對于序列化,Boost是這么定義的:

Here, we use the term "serialization" to mean the reversible deconstruction of an arbitrary set of C++ data structures to a sequence of bytes.? Such a system can be used to reconstitute an equivalent structure in another program context.? Depending on the context, this might used implement object persistence, remote parameter passing or other facility. In this system we use the term"archive" to refer to a specific rendering of this stream of bytes.? This could be a file of binary data, text data,? XML, or some other created by the user of this library.

這段英文很簡單,我相信大多數(shù)程序員都能看的懂。

基本上Boost序列化可以分為兩種模式:侵入式(intrusive)和非侵入式(non-intrusive)

?

侵入式(intrusive)

先來看看侵入式。我們先來定義一個類,這個類支持序列化:

??? class CMyData
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?ar & _tag;
?? ??? ??? ?ar & _text;
?? ??? ?}
??? ?
?? ??? ?
??? public:
?? ??? ?CMyData():_tag(0), _text(""){}
??? ?
?? ??? ?CMyData(int tag, std::string text):_tag(tag), _text(text){}
??? ?
?? ??? ?int GetTag() const {return _tag;}
?? ??? ?std::string GetText() const {return _text;}
??? ?
??? private:
?? ??? ?int _tag;
?? ??? ?std::string _text;
??? };


?

其中,我們可以看到這些代碼:

??? friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?ar & _tag;
?? ??? ??? ?ar & _text;
?? ??? ?}

這些代碼就是用來實現(xiàn)序列化的,這些代碼存在于類CMyData中,也就是為什么稱這種模式是“侵入式”的原因了。

看看怎么把這個對象序列化。這里,我把這個對象以二進制的方式保存到了一個ostringstream中了,當然也可以保存為其他形式,比如XML。也可以保存到文件中。代碼都是類似的。

??? void TestArchive1()
??? {
?? ??? ?CMyData d1(2012, "China, good luck");
?? ??? ?std::ostringstream os;
?? ??? ?boost::archive::binary_oarchive oa(os);
?? ??? ?oa << d1;//序列化到一個ostringstream里面
??? ?
?? ??? ?std::string content = os.str();//content保存了序列化后的數(shù)據(jù)。
??? ?
?? ??? ?CMyData d2;
?? ??? ?std::istringstream is(content);
?? ??? ?boost::archive::binary_iarchive ia(is);
?? ??? ?ia >> d2;//從一個保存序列化數(shù)據(jù)的string里面反序列化,從而得到原來的對象。
??? ?
?? ??? ?std::cout << "CMyData tag: " << d2.GetTag() << ", text: " << d2.GetText() << "\n";
??? }

先生成一個CMyData的對象,然后序列化保存到一個ostringstream中,接著再把這個序列化的數(shù)據(jù)反序列化,得到原來的對象,打印出來,我們會發(fā)現(xiàn)反序列化的對象的數(shù)據(jù)成員跟序列化前的對象一模一樣。哈哈,成功了,簡單吧。至于Boost怎么實現(xiàn)這個過程的,看Boost源代碼吧,Boost的網(wǎng)站上也有一些介紹。Boost確實設計的很巧妙,不得不佩服那幫家伙。

那么可以序列化CMyData的子類嗎,答案是肯定的。其實很簡單就是在子類的序列化函數(shù)里面先序列化基類的。看看代碼就明白了:

??? class CMyData_Child: public CMyData
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?// serialize base class information
?? ??? ??? ?ar & boost::serialization::base_object<CMyData>(*this);
?? ??? ??? ?ar & _number;
?? ??? ?}
??? ?
??? ?
??? public:
?? ??? ?CMyData_Child():_number(0.0){}
??? ?
?? ??? ?CMyData_Child(int tag, std::string text, float number):CMyData(tag, text), _number(number){}
??? ?
?? ??? ?float GetNumber() const{return _number;}
??? ?
??? private:
?? ??? ?float _number;
??? };
??? ?
??? void TestArchive3()
??? {
?? ??? ?CMyData_Child d1(2012, "China, good luck", 1.2);
?? ??? ?std::ostringstream os;
?? ??? ?boost::archive::binary_oarchive oa(os);
?? ??? ?oa << d1;//序列化到一個ostringstream里面
??? ?
?? ??? ?std::string content = os.str();//content保存了序列化后的數(shù)據(jù)。
??? ?
?? ??? ?CMyData_Child d2;
?? ??? ?std::istringstream is(content);
?? ??? ?boost::archive::binary_iarchive ia(is);
?? ??? ?ia >> d2;//從一個保存序列化數(shù)據(jù)的string里面反序列化,從而得到原來的對象。
??? ?
?? ??? ?std::cout << "CMyData_Child tag: " << d2.GetTag() << ", text: " << d2.GetText() << ", number: "<<d2.GetNumber() << "\n";
??? }


?

?

非侵入式(non-intrusive)

侵入式的缺點就是需要在class里面加一些代碼,那么有時候可能這個class已經(jīng)存在了,或者我們并不想往里面加入這么些代碼,那么怎么辦呢?ok,輪到非侵入式出場了。

比方說我們有這么個類:

??? class CMyData2
??? {
??? public:
?? ??? ?CMyData2():_tag(0), _text(""){}
??? ?
?? ??? ?CMyData2(int tag, std::string text):_tag(tag), _text(text){}
??? ?
?? ??? ?int _tag;
?? ??? ?std::string _text;
??? };

那么我們可以這么序列化:

??? namespace boost {
?? ??? ?namespace serialization {
??? ?
?? ??? ??? ?template<class Archive>
?? ??? ??? ?void serialize(Archive & ar, CMyData2 & d, const unsigned int version)
?? ??? ??? ?{
?? ??? ??? ??? ?ar & d._tag;
?? ??? ??? ??? ?ar & d._text;
?? ??? ??? ?}
??? ?
?? ??? ?} // namespace serialization
??? } // namespace boost


?然后調(diào)用還是跟侵入式一模一樣,看:

??? void TestArchive2()
??? {
?? ??? ?CMyData2 d1(2012, "China, good luck");
?? ??? ?std::ostringstream os;
?? ??? ?boost::archive::binary_oarchive oa(os);
?? ??? ?oa << d1;//序列化到一個ostringstream里面
??? ?
?? ??? ?std::string content = os.str();//content保存了序列化后的數(shù)據(jù)。
??? ?
?? ??? ?CMyData2 d2;
?? ??? ?std::istringstream is(content);
?? ??? ?boost::archive::binary_iarchive ia(is);
?? ??? ?ia >> d2;//從一個保存序列化數(shù)據(jù)的string里面反序列化,從而得到原來的對象。
??? ?
?? ??? ?std::cout << "CMyData2 tag: " << d2._tag << ", text: " << d2._text << "\n";
??? }


成功。跟侵入式相比,非侵入式省去了在具體類里面加入序列化代碼。但是我們看看非侵入式模式里面的類的定義,我們會發(fā)現(xiàn)我們把數(shù)據(jù)成員搞成public的了。這是為什么呢?看看這個就明白了:

??? template<class Archive>
?? ??? ??? ?void serialize(Archive & ar, CMyData2 & d, const unsigned int version)
?? ??? ??? ?{
?? ??? ??? ??? ?ar & d._tag;
?? ??? ??? ??? ?ar & d._text;
?? ??? ??? ?}

原來序列化函數(shù)需要訪問數(shù)據(jù)成員。這就是非侵入式的一個缺點了:需要把數(shù)據(jù)成員暴露出來。通過直接訪問數(shù)據(jù)成員也好,通過函數(shù)訪問也好,總之需要這個類把數(shù)據(jù)成員暴露出來,這樣序列化函數(shù)才能訪問。世界上沒有十全十美的東西,有時我們得到一個東西,往往會失去另外一個東西,不是嗎?

侵入式和非侵入式各有各的用處,看具體情況來決定用哪個了。

非侵入式可以支持子類序列化嗎?可以。跟侵入式一樣,其實也就是先序列化一下基類,然后再序列化子類的數(shù)據(jù)成員。看代碼:

??? class CMyData2_Child: public CMyData2
??? {
??? public:
?? ??? ?CMyData2_Child():_number(0.0){}
??? ?
?? ??? ?CMyData2_Child(int tag, std::string text, float number):CMyData2(tag, text), _number(number){}
??? ?
?? ??? ?float _number;
??? };
??? ?
??? namespace boost {
?? ??? ?namespace serialization {
??? ?
?? ??? ??? ?template<class Archive>
?? ??? ??? ?void serialize(Archive & ar, CMyData2_Child & d, const unsigned int version)
?? ??? ??? ?{
?? ??? ??? ??? ?// serialize base class information
?? ??? ??? ??? ?ar & boost::serialization::base_object<CMyData2>(d);
?? ??? ??? ??? ?ar & d._number;
?? ??? ??? ?}
??? ?
?? ??? ?} // namespace serialization
??? } // namespace boost
??? ?
??? void TestArchive4()
??? {
?? ??? ?CMyData2_Child d1(2012, "test non-intrusive child class", 5.6);
?? ??? ?std::ostringstream os;
?? ??? ?boost::archive::binary_oarchive oa(os);
?? ??? ?oa << d1;//序列化到一個ostringstream里面
??? ?
?? ??? ?std::string content = os.str();//content保存了序列化后的數(shù)據(jù)。
??? ?
?? ??? ?CMyData2_Child d2;
?? ??? ?std::istringstream is(content);
?? ??? ?boost::archive::binary_iarchive ia(is);
?? ??? ?ia >> d2;//從一個保存序列化數(shù)據(jù)的string里面反序列化,從而得到原來的對象。
??? ?
?? ??? ?std::cout << "CMyData2_Child tag: " << d2._tag << ", text: " << d2._text << ", number: "<<d2._number<<"\n";
??? }

?

好了,以上就是序列化的簡單用法。接下里我們來重點關注一下數(shù)據(jù)成員的序列化,假如我們的類里面有指針,那么還能序列化嗎?比如下面的代碼,會發(fā)生什么事?


序列化指針數(shù)據(jù)成員

??? class CMyData
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?ar & _tag;
?? ??? ??? ?ar & _text;
?? ??? ?}
??? ?
??? ?
??? public:
?? ??? ?CMyData():_tag(0), _text(""){}
??? ?
?? ??? ?CMyData(int tag, std::string text):_tag(tag), _text(text){}
??? ?
?? ??? ?int GetTag() const {return _tag;}
?? ??? ?std::string GetText() const {return _text;}
??? ?
??? private:
?? ??? ?int _tag;
?? ??? ?std::string _text;
??? };
??? class CMyData_Child: public CMyData
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?// serialize base class information
?? ??? ??? ?ar & boost::serialization::base_object(*this);
?? ??? ??? ?ar & _number;
?? ??? ?}
??? ?
??? ?
??? public:
?? ??? ?CMyData_Child():_number(0.0){}
??? ?
?? ??? ?CMyData_Child(int tag, std::string text, float number):CMyData(tag, text), _number(number){}
??? ?
?? ??? ?float GetNumber() const{return _number;}
??? ?
??? private:
?? ??? ?float _number;
??? };
??? class CMyData_Container
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?for(int i = 0; i < 3; i++)
?? ??? ??? ?{
?? ??? ??? ??? ?ar & pointers[i];
?? ??? ??? ?}
?? ??? ?}
??? public:
?? ??? ?CMyData* pointers[3];
??? };
??? ?
??? void TestPointerArchive()
??? {
?? ??? ?std::string content;
?? ??? ?{
?? ??? ??? ?CMyData d1(1, "a");
?? ??? ??? ?CMyData_Child d2(2, "b", 1.5);
??? ?
?? ??? ??? ?CMyData_Container containter;
?? ??? ??? ?containter.pointers[0] = &d1;
?? ??? ??? ?containter.pointers[1] = &d2;
?? ??? ??? ?containter.pointers[2] = &d1;
??? ?
?? ??? ??? ?std::ostringstream os;
?? ??? ??? ?boost::archive::binary_oarchive oa(os);
?? ??? ??? ?oa << containter;
??? ?
?? ??? ??? ?content = os.str();
?? ??? ?}
??? ?
?? ??? ?//反序列化
?? ??? ?{
?? ??? ??? ?CMyData_Container container;
?? ??? ??? ?std::istringstream is(content);
?? ??? ??? ?boost::archive::binary_iarchive ia(is);
?? ??? ??? ?ia >> container;
??? ?
?? ??? ??? ?for (int i = 0; i < 3; i++)
?? ??? ??? ?{
?? ??? ??? ??? ?CMyData* d = container.pointers[i];
?? ??? ??? ??? ?std::cout << "pointer" << i + 1 <<": " << d->GetText() << "\n";
??? ?
?? ??? ??? ??? ?if (i == 1)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?CMyData_Child* child = reinterpret_cast<CMyData_Child*>(d);
?? ??? ??? ??? ??? ?std::cout << "pointer" << i + 1 <<", number: " << child->GetNumber() << "\n";
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
??? }


?注意,我們在CMyData_Container對象里面放進去了3個指針,其中第二個指針是CMyData的子類。

然后進行序列化,再反序列化,我們會發(fā)現(xiàn),第一個,第三個指針輸出了正確的信息,然而第二個指針有點問題,本身我們存進去的時候是個CMyData_Child 對象,通過測試我們可以發(fā)現(xiàn),CMyData_Child的基類部分,我們可以正確的輸出,但是CMyData_Child的成員_number,卻得不到正確信息。這是個問題。

也就是說,序列化指針是可以的,但是需要注意多態(tài)的問題。假如我們不需要考慮多態(tài),那么以上的代碼就可以正常工作了。但是如果要考慮多態(tài)的問題,那么就得特殊處理了。下面再來介紹序列化多態(tài)指針。

?

?序列化多態(tài)指針數(shù)據(jù)成員

上一個章節(jié)里面演示了如果序列化指針成員,但是有個問題,就是當基類指針指向一個派生類對象的時候,然后序列化這個指針,那么派生類的信息就被丟掉了。這個很不好。那么怎么來解決這個問題呢?很幸運,Boost的開發(fā)人員已經(jīng)考慮到了這個問題。再一次感受到Boost的強大。

有兩種方法可以解決這個問題:

1. registration

2. export

具體可以參考: http://www.boost.org/doc/libs/1_51_0/libs/serialization/doc/serialization.html#derivedpointers

這里我們介紹第二種方式,這種方式比較簡單,也用的比較好。就是通過一個宏把派生類給命名一下。

這個關鍵的宏是:BOOST_CLASS_EXPORT_GUID

相關解釋:

The macro BOOST_CLASS_EXPORT_GUID associates a string literal with a class. In the above example we've used a string rendering of the class name. If a object of such an "exported" class is serialized through a pointer and is otherwise unregistered, the "export" string is? included in the archive. When the archive? is later read, the string literal is used to find the class which? should be created by the serialization library. This permits each class to be in a separate header file along with its? string identifier. There is no need to maintain a separate "pre-registration"? of derived classes that might be serialized.? This method of registration is referred to as "key export".

如何使用這個神奇的宏BOOST_CLASS_EXPORT_GUID來實現(xiàn)序列化指向派生類的指針呢?先給出代碼:

??? class CMyData
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?ar & _tag;
?? ??? ??? ?ar & _text;
?? ??? ?}
??? ?
?? ??? ?
??? public:
?? ??? ?CMyData():_tag(0), _text(""){}
??? ?
?? ??? ?CMyData(int tag, std::string text):_tag(tag), _text(text){}
?? ??? ?virtual ~CMyData(){}
??? ?
?? ??? ?int GetTag() const {return _tag;}
?? ??? ?std::string GetText() const {return _text;}
??? ?
??? private:
?? ??? ?int _tag;
?? ??? ?std::string _text;
??? };
??? ?
??? class CMyData_Child: public CMyData
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?// serialize base class information
?? ??? ??? ?ar & boost::serialization::base_object<CMyData>(*this);
?? ??? ??? ?ar & _number;
?? ??? ?}
??? ?
??? ?
??? public:
?? ??? ?CMyData_Child():_number(0.0){}
??? ?
?? ??? ?CMyData_Child(int tag, std::string text, float number):CMyData(tag, text), _number(number){}
??? ?
?? ??? ?float GetNumber() const{return _number;}
??? ?
??? private:
?? ??? ?float _number;
??? };
??? ?
??? BOOST_CLASS_EXPORT_GUID(CMyData_Child, "CMyData_Child")
??? ?
??? class CMyData_Container
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?for(int i = 0; i < 3; i++)
?? ??? ??? ?{
?? ??? ??? ??? ?ar & pointers[i];
?? ??? ??? ?}
?? ??? ?}
??? public:
?? ??? ?CMyData* pointers[3];
??? };
??? ?
??? ?
??? void TestPointerArchive()
??? {
?? ??? ?std::string content;
?? ??? ?{
?? ??? ??? ?CMyData d1(1, "a");
?? ??? ??? ?CMyData_Child d2(2, "b", 1.5);
??? ?
?? ??? ??? ?CMyData_Container containter;
?? ??? ??? ?containter.pointers[0] = &d1;
?? ??? ??? ?containter.pointers[1] = &d2;
?? ??? ??? ?containter.pointers[2] = &d1;
??? ?
?? ??? ??? ?std::ostringstream os;
?? ??? ??? ?boost::archive::binary_oarchive oa(os);
?? ??? ??? ?oa << containter;
??? ?
?? ??? ??? ?content = os.str();
?? ??? ?}
??? ?
?? ??? ?//·′DòáD?ˉ
?? ??? ?{
?? ??? ??? ?CMyData_Container container;
?? ??? ??? ?std::istringstream is(content);
?? ??? ??? ?boost::archive::binary_iarchive ia(is);
?? ??? ??? ?ia >> container;
??? ?
?? ??? ??? ?for (int i = 0; i < 3; i++)
?? ??? ??? ?{
?? ??? ??? ??? ?CMyData* d = container.pointers[i];
?? ??? ??? ??? ?std::cout << "pointer" << i + 1 <<": " << d->GetText() << "\n";
??? ?
?? ??? ??? ??? ?if (i == 1)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?CMyData_Child* child = reinterpret_cast<CMyData_Child*>(d);
?? ??? ??? ??? ??? ?std::cout << "pointer" << i + 1 <<", number: " << child->GetNumber() << "\n";
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
??? }


這次我們可以正確的讀取到第二個指針指向的對象了,可以看到_number的爭取值了。

把代碼和上個版本想比較,我們會發(fā)現(xiàn)2個不同:

1. CMyData類里面多了個虛的析構(gòu)函數(shù);

2. 調(diào)用BOOST_CLASS_EXPORT_GUID給派生類CMyData_Child綁定一個字符串。

第二點很容易理解,就是給某個派生類命名一下,這樣就可以當作一個key來找到相應的類。那么第一點為什么要增加一個虛析構(gòu)函數(shù)呢?是我無意中添加的嗎?當然不是,其實這個是序列化指向派生類的指針的其中一個關鍵。先看Boost網(wǎng)站上面的一段描述:

It turns out that the kind of object serialized depends upon whether the base class (base in this case) is polymophic or not. Ifbase is not polymorphic, that is if it has no virtual functions, then an object of the typebasewill be serialized. Information in any derived classes will be lost. If this is what is desired (it usually isn't) then no other effort is required.

If the base class is polymorphic, an object of the most derived type (derived_oneorderived_twoin this case) will be serialized.? The question of which type of object is to be serialized is (almost) automatically handled by the library.

ok,通過這段描述,我們發(fā)現(xiàn)Boost序列化庫會判斷基類是不是多態(tài)的。判斷的依據(jù)就是這個基類里面有沒有虛函數(shù)。我們知道,當一個類里面有虛函數(shù)的時候,C++編譯器會自動給這個類增加一個成員:_vfptr,就是虛函數(shù)表指針。我沒有花太多時間去看Boost有關這部分的源代碼,但是我猜測Boost是根據(jù)這個_vfptr來判斷是需要序列化基類,還是派生類的。我們增加一個虛析構(gòu)函數(shù)的目的也就是讓CMyData產(chǎn)生一個_vfptr。我們可以試一下把上面的代碼里面的析構(gòu)函數(shù)改成非虛的,那么派生類序列化就會失敗,跟上一個章節(jié)得到相同的結(jié)果。至于Boost怎么知道該序列化哪個派生類,相信這個是BOOST_CLASS_EXPORT_GUID的功勞,至于怎么實現(xiàn),還是需要看源代碼,但是我自己沒有仔細研究過,有興趣的朋友可以學習Boost的源代碼。Boost的設計很巧妙,我們可以學到不少東西。當然這個得有時間細細學習。好了,序列化指向派生類指針就2個要點:

1. 讓Boost知道基類是多態(tài)的,其實就是確保基類里面有個虛函數(shù);

2. 通過BOOST_CLASS_EXPORT_GUID給派生類綁定一個字符串,當作一個key。

?

至于第一種序列化指向派生類的基類指針:registration,可以參考http://www.boost.org/doc/libs/1_51_0/libs/serialization/doc/serialization.html#derivedpointers,上面講的非常清楚。我本人很少使用這種方式,這里也就略過不講了。

?

序列化數(shù)組

一個小細節(jié),上面講到的序列化指針章節(jié)里面,我們看到代碼:

??? class CMyData_Container
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?for(int i = 0; i < 3; i++)
?? ??? ??? ?{
?? ??? ??? ??? ?ar & pointers[i];
?? ??? ??? ?}
?? ??? ?}
??? public:
?? ??? ?CMyData* pointers[3];
??? };

其中的序列化函數(shù)里面有個for循環(huán),難道每次序列化一個數(shù)組都需要弄一個for語句嗎,這個是不是可以改進呢?答案是肯定的。Boost自己會檢測數(shù)組。也就是說我們可以把代碼改成下面的形式:

??? class CMyData_Container
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?ar & pointers;
?? ??? ?}
??? public:
?? ??? ?CMyData* pointers[3];
??? };

代碼短了很多,方便吧。
?

?支持STL容器

?上面我們使用了一個普通數(shù)組來保存指針,我相信在平常寫程序過程中,大家都會使用STL容器,比如list,map,array等等。至少我自己是經(jīng)常使用的。那么Boost序列化庫可以序列化STL容器嗎?很幸運,Boost序列化庫已經(jīng)支持了STL容器。原話是:

The above example uses an array of members.? More likely such an application would use an STL collection for such a purpose. The serialization library contains code for serialization of all STL classes.? Hence, the reformulation below will also work as one would expect.

?我們一開始就是用std::string作為CMyData的一個成員,我們不需要做任何工作就可以直接序列化std::string,這是因為Boost序列化庫已經(jīng)支持std::string了。從上面的英文描述里面可以看到Boost serialization庫可以支持所有STL類,神奇吧。至少我本人經(jīng)常使用std::list, vector, map, string等,都可以正常工作。下面的代碼使用std::vector代替了普通數(shù)組,可以正常工作。

??? class CMyData
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?ar & _tag;
?? ??? ??? ?ar & _text;
?? ??? ?}
??? ?
?? ??? ?
??? public:
?? ??? ?CMyData():_tag(0), _text(""){}
??? ?
?? ??? ?CMyData(int tag, std::string text):_tag(tag), _text(text){}
?? ??? ?virtual ~CMyData(){}
??? ?
?? ??? ?int GetTag() const {return _tag;}
?? ??? ?std::string GetText() const {return _text;}
??? ?
??? private:
?? ??? ?int _tag;
?? ??? ?std::string _text;
??? };
??? ?
??? class CMyData_Child: public CMyData
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?// serialize base class information
?? ??? ??? ?ar & boost::serialization::base_object<CMyData>(*this);
?? ??? ??? ?ar & _number;
?? ??? ?}
??? ?
??? ?
??? public:
?? ??? ?CMyData_Child():_number(0.0){}
??? ?
?? ??? ?CMyData_Child(int tag, std::string text, float number):CMyData(tag, text), _number(number){}
??? ?
?? ??? ?float GetNumber() const{return _number;}
??? ?
??? private:
?? ??? ?float _number;
??? };
??? ?
??? BOOST_CLASS_EXPORT_GUID(CMyData_Child, "CMyData_Child")
??? ?
??? //ê1ó?STLèY?÷
??? class CMyData_ContainerSTL
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?ar & vPointers;
?? ??? ?}
??? public:
?? ??? ?std::vector<CMyData*> vPointers;
??? };
??? ?
??? ?
??? ?
??? void TestPointerArchiveWithSTLCollections()
??? {
?? ??? ?std::string content;
?? ??? ?{
?? ??? ??? ?CMyData d1(1, "parent obj");
?? ??? ??? ?CMyData_Child d2(2, "child obj", 2.5);
??? ?
?? ??? ??? ?CMyData_ContainerSTL containter;
?? ??? ??? ?containter.vPointers.push_back(&d1);
?? ??? ??? ?containter.vPointers.push_back(&d2);
?? ??? ??? ?containter.vPointers.push_back(&d1);
?? ??? ??? ?
??? ?
?? ??? ??? ?std::ostringstream os;
?? ??? ??? ?boost::archive::binary_oarchive oa(os);
?? ??? ??? ?oa << containter;
??? ?
?? ??? ??? ?content = os.str();
?? ??? ?}
??? ?
?? ??? ?//·′DòáD?ˉ
?? ??? ?{
?? ??? ??? ?CMyData_ContainerSTL container;
?? ??? ??? ?std::istringstream is(content);
?? ??? ??? ?boost::archive::binary_iarchive ia(is);
?? ??? ??? ?ia >> container;
??? ?
?? ??? ??? ?std::cout<<"Test STL collections:\n";
?? ??? ??? ?BOOST_FOREACH(CMyData* p, container.vPointers)
?? ??? ??? ?{
?? ??? ??? ??? ?std::cout << "object text: " << p->GetText() << "\n";
??? ?
?? ??? ??? ??? ?CMyData_Child* child = dynamic_cast<CMyData_Child*>(p);
?? ??? ??? ??? ?if (child)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?std::cout << "child object number: " << child->GetNumber() << "\n";
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
??? }

一不小心就用到了BOOST_FOREACH,看來這個確實很好用啊,呵呵。省去了寫很長的iterator來遍歷整個vector。

?

class版本
再來考慮一個問題,比方說現(xiàn)在我們程序升級了,然后把某個類給升級了一下,加了一個成員,那么之前保存的序列化的數(shù)據(jù)還能匹配到新的類嗎?看一下序列化函數(shù),我們會發(fā)現(xiàn)這個序列化函數(shù)有個參數(shù),叫做version

template<class Archive>
?void serialize(Archive& ar, const unsigned int version)

通過這個參數(shù),我們就可以解決class版本的問題。看這段描述

In general, the serialization library stores a version number in the archive for each class serialized.? By default this version number is 0. When the archive is loaded, the version number under which it was saved is read.

也就是說如果我們不刻意指定version,那么Boost序列化庫就會默認設置為0并且保存到序列化結(jié)果中。

如果我們要標記不同的class版本,可以使用宏BOOST_CLASS_VERSION,比如

BOOST_CLASS_VERSION(CMyData, 1)

?具體這里就不舉例了。參考Boost說明。

?

save和load分開

?一直到現(xiàn)在我們都是用了一個序列化函數(shù)

template<class Archive>
?void serialize(Archive& ar, const unsigned int version)

其實,序列化包括序列化和發(fā)序列化兩部分,或者稱之為save和load,甚至mashalling,unmarshalling。反正就這個意思。

還有一個奇怪的地方,就是通常我們輸入輸出是用<<和>>的,那么在函數(shù)serialize里面我們用了&。其實這個是Boost對&做了一個封裝。假如現(xiàn)在是做序列化,那么&就等同于<<,假如是反序列化,那么&就等同于>>。然后序列化和反序列化統(tǒng)統(tǒng)用一個函數(shù)serialize來實現(xiàn)。這也體現(xiàn)了Boost的巧妙設計。

那么如果有特殊需求,我們需要把序列化和反序列化分開,應該怎么實現(xiàn)呢?

就好比上面的class版本問題,save和load可能就是不一樣的,因為load需要考慮兼容舊的版本。這里就偷懶使用Boost文檔上的例子了。我們可以看到save和load是分開的。

??? #include <boost/serialization/list.hpp>
??? #include <boost/serialization/string.hpp>
??? #include <boost/serialization/version.hpp>
??? #include <boost/serialization/split_member.hpp>
??? ?
??? class bus_route
??? {
??????? friend class boost::serialization::access;
??????? std::list<bus_stop *> stops;
??????? std::string driver_name;
??????? template<class Archive>
??????? void save(Archive & ar, const unsigned int version) const
??????? {
??????????? // note, version is always the latest when saving
??????????? ar? & driver_name;
??????????? ar? & stops;
??????? }
??????? template<class Archive>
??????? void load(Archive & ar, const unsigned int version)
??????? {
??????????? if(version > 0)
??????????????? ar & driver_name;
??????????? ar? & stops;
??????? }
??????? BOOST_SERIALIZATION_SPLIT_MEMBER()
??? public:
??????? bus_route(){}
??? };
??? ?
??? BOOST_CLASS_VERSION(bus_route, 1)

注意需要使用宏BOOST_SERIALIZATION_SPLIT_MEMBER()來告訴Boost序列化庫使用save和load代替serialize函數(shù)。

到這里,我們幾乎把Boost序列化庫所有的內(nèi)容都介紹完畢了。這個庫是相當?shù)膎ice,基本可以cover所有的case。而且就開源庫來講,Boost的說明文檔真的算是很好的了。基本上都有詳細的說明,就序列化庫而言,直接看這個頁面就基本ok了,http://www.boost.org/doc/libs/1_51_0/libs/serialization/doc/tutorial.html 相當?shù)脑敿殹1M管讀英文比較累,但是可以獲得原汁原味的第一手權(quán)威資料,花這些功夫還是值得的。

我的例子里面使用了二進制流來保存序列化后的數(shù)據(jù),其實還有其他的archive格式,比如text,XML等等。甚至我們可以自己來實現(xiàn)序列化格式。Boost已經(jīng)定義了一個統(tǒng)一的接口,我們要實現(xiàn)自己的格式,只需要繼承相應的Boost::archive里面的類就可以了。

好了,寫完了,希望對大家有點幫助。如有錯誤,歡迎指出。

?

附,完整測試代碼,使用這段代碼前需要確保VISUAL STUDIO已經(jīng)設置了Boost的路徑。

??? // Serialization.cpp : Defines the entry point for the console application.
??? //
??? ?
??? #include "stdafx.h"
??? ?
??? #include "boost/serialization/serialization.hpp"
??? #include "boost/archive/binary_oarchive.hpp"
??? #include "boost/archive/binary_iarchive.hpp"
??? #include <boost/serialization/export.hpp>
??? #include "boost/foreach.hpp"
??? #include "boost/any.hpp"
??? #include <boost/serialization/vector.hpp>
??? ?
??? ?
??? ?
??? #include <string>
??? #include <Windows.h>
??? #include <iostream>
??? #include <sstream>
??? #include <vector>
??? ?
??? ?
??? //測試序列化
??? class CMyData
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?ar & _tag;
?? ??? ??? ?ar & _text;
?? ??? ?}
??? ?
?? ??? ?
??? public:
?? ??? ?CMyData():_tag(0), _text(""){}
??? ?
?? ??? ?CMyData(int tag, std::string text):_tag(tag), _text(text){}
?? ??? ?virtual ~CMyData(){}
??? ?
?? ??? ?int GetTag() const {return _tag;}
?? ??? ?std::string GetText() const {return _text;}
??? ?
??? private:
?? ??? ?int _tag;
?? ??? ?std::string _text;
??? };
??? ?
??? ?
??? void TestArchive1()
??? {
?? ??? ?std::string content;
??? ?
?? ??? ?{
?? ??? ??? ?CMyData d1(2012, "China, good luck");
?? ??? ??? ?std::ostringstream os;
?? ??? ??? ?boost::archive::binary_oarchive oa(os);
?? ??? ??? ?oa << d1;//序列化到一個ostringstream里面
??? ?
?? ??? ??? ?content = os.str();//content保存了序列化后的數(shù)據(jù)。
?? ??? ?}
?? ??? ?
??? ?
?? ??? ?{
?? ??? ??? ?CMyData d2;
?? ??? ??? ?std::istringstream is(content);
?? ??? ??? ?boost::archive::binary_iarchive ia(is);
?? ??? ??? ?ia >> d2;//從一個保存序列化數(shù)據(jù)的string里面反序列化,從而得到原來的對象。
??? ?
?? ??? ??? ?std::cout << "CMyData tag: " << d2.GetTag() << ", text: " << d2.GetText() << "\n";
?? ??? ?}
?? ??? ?
??? }
??? ?
??? ?
??? class CMyData2
??? {
??? public:
?? ??? ?CMyData2():_tag(0), _text(""){}
??? ?
?? ??? ?CMyData2(int tag, std::string text):_tag(tag), _text(text){}
??? ?
?? ??? ?int _tag;
?? ??? ?std::string _text;
??? };
??? ?
??? namespace boost {
?? ??? ?namespace serialization {
??? ?
?? ??? ??? ?template<class Archive>
?? ??? ??? ?void serialize(Archive & ar, CMyData2 & d, const unsigned int version)
?? ??? ??? ?{
?? ??? ??? ??? ?ar & d._tag;
?? ??? ??? ??? ?ar & d._text;
?? ??? ??? ?}
??? ?
?? ??? ?} // namespace serialization
??? } // namespace boost
??? ?
??? void TestArchive2()
??? {
?? ??? ?CMyData2 d1(2012, "China, good luck");
?? ??? ?std::ostringstream os;
?? ??? ?boost::archive::binary_oarchive oa(os);
?? ??? ?oa << d1;//序列化到一個ostringstream里面
??? ?
?? ??? ?std::string content = os.str();//content保存了序列化后的數(shù)據(jù)。
??? ?
?? ??? ?CMyData2 d2;
?? ??? ?std::istringstream is(content);
?? ??? ?boost::archive::binary_iarchive ia(is);
?? ??? ?ia >> d2;//從一個保存序列化數(shù)據(jù)的string里面反序列化,從而得到原來的對象。
??? ?
?? ??? ?std::cout << "CMyData2 tag: " << d2._tag << ", text: " << d2._text << "\n";
??? }
??? ?
??? ?
??? //序列化子類,侵入式
??? class CMyData_Child: public CMyData
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?// serialize base class information
?? ??? ??? ?ar & boost::serialization::base_object<CMyData>(*this);
?? ??? ??? ?ar & _number;
?? ??? ?}
??? ?
??? ?
??? public:
?? ??? ?CMyData_Child():_number(0.0){}
??? ?
?? ??? ?CMyData_Child(int tag, std::string text, float number):CMyData(tag, text), _number(number){}
??? ?
?? ??? ?float GetNumber() const{return _number;}
??? ?
??? private:
?? ??? ?float _number;
??? };
??? ?
??? BOOST_CLASS_EXPORT_GUID(CMyData_Child, "CMyData_Child")
??? ?
??? ?
??? void TestArchive3()
??? {
?? ??? ?CMyData_Child d1(2012, "China, good luck", 1.2);
?? ??? ?std::ostringstream os;
?? ??? ?boost::archive::binary_oarchive oa(os);
?? ??? ?oa << d1;//序列化到一個ostringstream里面
??? ?
?? ??? ?std::string content = os.str();//content保存了序列化后的數(shù)據(jù)。
??? ?
?? ??? ?CMyData_Child d2;
?? ??? ?std::istringstream is(content);
?? ??? ?boost::archive::binary_iarchive ia(is);
?? ??? ?ia >> d2;//從一個保存序列化數(shù)據(jù)的string里面反序列化,從而得到原來的對象。
??? ?
?? ??? ?std::cout << "CMyData_Child tag: " << d2.GetTag() << ", text: " << d2.GetText() << ", number: "<<d2.GetNumber() << "\n";
??? }
??? ?
??? //序列化子類,非侵入式
??? class CMyData2_Child: public CMyData2
??? {
??? public:
?? ??? ?CMyData2_Child():_number(0.0){}
??? ?
?? ??? ?CMyData2_Child(int tag, std::string text, float number):CMyData2(tag, text), _number(number){}
??? ?
?? ??? ?float _number;
??? };
??? ?
??? namespace boost {
?? ??? ?namespace serialization {
??? ?
?? ??? ??? ?template<class Archive>
?? ??? ??? ?void serialize(Archive & ar, CMyData2_Child & d, const unsigned int version)
?? ??? ??? ?{
?? ??? ??? ??? ?// serialize base class information
?? ??? ??? ??? ?ar & boost::serialization::base_object<CMyData2>(d);
?? ??? ??? ??? ?ar & d._number;
?? ??? ??? ?}
??? ?
?? ??? ?} // namespace serialization
??? } // namespace boost
??? ?
??? void TestArchive4()
??? {
?? ??? ?CMyData2_Child d1(2012, "test non-intrusive child class", 5.6);
?? ??? ?std::ostringstream os;
?? ??? ?boost::archive::binary_oarchive oa(os);
?? ??? ?oa << d1;//序列化到一個ostringstream里面
??? ?
?? ??? ?std::string content = os.str();//content保存了序列化后的數(shù)據(jù)。
??? ?
?? ??? ?CMyData2_Child d2;
?? ??? ?std::istringstream is(content);
?? ??? ?boost::archive::binary_iarchive ia(is);
?? ??? ?ia >> d2;//從一個保存序列化數(shù)據(jù)的string里面反序列化,從而得到原來的對象。
??? ?
?? ??? ?std::cout << "CMyData2_Child tag: " << d2._tag << ", text: " << d2._text << ", number: "<<d2._number<<"\n";
??? }
??? ?
??? ?
??? //指針數(shù)據(jù)成員
??? ?
??? class CMyData_Container
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?ar & pointers;
?? ??? ?}
??? public:
?? ??? ?CMyData* pointers[3];
??? };
??? ?
??? ?
??? ?
??? void TestPointerArchive()
??? {
?? ??? ?std::string content;
?? ??? ?{
?? ??? ??? ?CMyData d1(1, "a");
?? ??? ??? ?CMyData_Child d2(2, "b", 1.5);
??? ?
?? ??? ??? ?CMyData_Container containter;
?? ??? ??? ?containter.pointers[0] = &d1;
?? ??? ??? ?containter.pointers[1] = &d2;
?? ??? ??? ?containter.pointers[2] = &d1;
??? ?
?? ??? ??? ?std::ostringstream os;
?? ??? ??? ?boost::archive::binary_oarchive oa(os);
?? ??? ??? ?oa << containter;
??? ?
?? ??? ??? ?content = os.str();
?? ??? ?}
??? ?
?? ??? ?//反序列化
?? ??? ?{
?? ??? ??? ?CMyData_Container container;
?? ??? ??? ?std::istringstream is(content);
?? ??? ??? ?boost::archive::binary_iarchive ia(is);
?? ??? ??? ?ia >> container;
??? ?
?? ??? ??? ?for (int i = 0; i < 3; i++)
?? ??? ??? ?{
?? ??? ??? ??? ?CMyData* d = container.pointers[i];
?? ??? ??? ??? ?std::cout << "pointer" << i + 1 <<": " << d->GetText() << "\n";
??? ?
?? ??? ??? ??? ?if (i == 1)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?CMyData_Child* child = reinterpret_cast<CMyData_Child*>(d);
?? ??? ??? ??? ??? ?std::cout << "pointer" << i + 1 <<", number: " << child->GetNumber() << "\n";
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
??? }
??? ?
??? //使用STL容器
??? class CMyData_ContainerSTL
??? {
??? private:
?? ??? ?friend class boost::serialization::access;
??? ?
?? ??? ?template<class Archive>
?? ??? ?void serialize(Archive& ar, const unsigned int version)
?? ??? ?{
?? ??? ??? ?ar & vPointers;
?? ??? ?}
??? public:
?? ??? ?std::vector<CMyData*> vPointers;
??? };
??? ?
??? ?
??? ?
??? void TestPointerArchiveWithSTLCollections()
??? {
?? ??? ?std::string content;
?? ??? ?{
?? ??? ??? ?CMyData d1(1, "parent obj");
?? ??? ??? ?CMyData_Child d2(2, "child obj", 2.5);
??? ?
?? ??? ??? ?CMyData_ContainerSTL containter;
?? ??? ??? ?containter.vPointers.push_back(&d1);
?? ??? ??? ?containter.vPointers.push_back(&d2);
?? ??? ??? ?containter.vPointers.push_back(&d1);
?? ??? ??? ?
??? ?
?? ??? ??? ?std::ostringstream os;
?? ??? ??? ?boost::archive::binary_oarchive oa(os);
?? ??? ??? ?oa << containter;
??? ?
?? ??? ??? ?content = os.str();
?? ??? ?}
??? ?
?? ??? ?//反序列化
?? ??? ?{
?? ??? ??? ?CMyData_ContainerSTL container;
?? ??? ??? ?std::istringstream is(content);
?? ??? ??? ?boost::archive::binary_iarchive ia(is);
?? ??? ??? ?ia >> container;
??? ?
?? ??? ??? ?std::cout<<"Test STL collections:\n";
?? ??? ??? ?BOOST_FOREACH(CMyData* p, container.vPointers)
?? ??? ??? ?{
?? ??? ??? ??? ?std::cout << "object text: " << p->GetText() << "\n";
??? ?
?? ??? ??? ??? ?CMyData_Child* child = dynamic_cast<CMyData_Child*>(p);
?? ??? ??? ??? ?if (child)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?std::cout << "child object number: " << child->GetNumber() << "\n";
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
??? }
??? ?
??? int _tmain(int argc, _TCHAR* argv[])
??? {
?? ??? ?TestArchive1();
??? ?
?? ??? ?TestArchive2();
??? ?
?? ??? ?TestArchive3();
??? ?
?? ??? ?TestArchive4();
??? ?
?? ??? ?TestPointerArchive();
??? ?
?? ??? ?TestPointerArchiveWithSTLCollections();
??? ?
?? ??? ?return 0;
??? }
?

總結(jié)

以上是生活随笔為你收集整理的Boost - 序列化 (Serialization)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

国产精品专区h在线观看 | 国产在线日韩 | 亚洲乱码中文字幕综合 | 久久99久久99精品免视看婷婷 | 亚洲成人国产 | av电影不卡在线 | 日韩精品中文字幕在线不卡尤物 | 一区二区三区免费在线观看视频 | 久热只有精品 | 国产黄色精品在线观看 | av在线超碰 | 国产理论免费 | 亚洲国产精品成人精品 | 天天干天天插伊人网 | 国内精品视频久久 | 精品久久久久久亚洲 | 国产精品淫 | 日本丶国产丶欧美色综合 | 国产午夜精品久久久久久久久久 | 国产精品18p| www.伊人网.com| 日本中文在线 | 久久综合色一综合色88 | 国产精品99精品久久免费 | 亚洲码国产日韩欧美高潮在线播放 | 深夜精品福利 | 激情五月婷婷综合网 | 99精品在线免费观看 | 99久久精品免费看国产麻豆 | 久久免费的精品国产v∧ | 91麻豆产精品久久久久久 | 欧美成人黄 | 国产伦精品一区二区三区照片91 | 日本美女xx | 高清av中文字幕 | 男女激情麻豆 | av动态图片| 国产最新视频在线观看 | 免费观看福利视频 | 中文字幕乱码一区二区 | 久久久福利影院 | 国产精品手机看片 | 国产精品欧美久久久久无广告 | 国色天香在线观看 | 波多野结衣视频一区 | 91视频 - 88av| 伊人色综合网 | 久久影院一区 | 五月婷婷在线视频观看 | 婷婷丁香在线观看 | 成人一级免费电影 | 91香蕉视频 | 亚洲 欧美 另类人妖 | 国产色综合天天综合网 | 色视频在线免费观看 | 国产精品国产三级国产aⅴ入口 | 国产一区免费在线 | 女人高潮一级片 | 日韩黄色软件 | 一级免费看 | 成人黄色小说在线观看 | 欧美黑人性猛交 | 欧美精品久久久 | 亚州欧美视频 | 国产小视频你懂的在线 | 日本公乱妇视频 | 成人欧美亚洲 | 日韩欧美网站 | 久久久一本精品99久久精品66 | 99精品黄色 | 日韩一级电影在线观看 | 久久国产精品视频观看 | 免费看黄色小说的网站 | 久久久久女人精品毛片九一 | av 一区二区三区 | 久久99热这里只有精品国产 | 日韩一区二区三免费高清在线观看 | 欧美激情综合色综合啪啪五月 | 亚洲aⅴ乱码精品成人区 | 免费h精品视频在线播放 | 中文字幕在线免费观看视频 | 成人精品亚洲 | 日韩激情小视频 | 97狠狠操 | 国产亚洲综合在线 | 久艹在线免费观看 | 国产免费视频一区二区裸体 | 日韩电影在线一区 | 91亚洲国产| 亚洲精选视频在线 | 国产三级午夜理伦三级 | 特级毛片网站 | av一区二区在线观看中文字幕 | 精品极品在线 | 97精品国产一二三产区 | 最新中文字幕在线资源 | 亚洲无吗av | 国内视频1区 | 欧美日韩在线网站 | 黄色字幕网 | 亚洲国产一区在线观看 | 久久精品亚洲一区二区三区观看模式 | 99热精品国产一区二区在线观看 | 亚洲精品国偷拍自产在线观看蜜桃 | 在线只有精品 | 国产原创91 | 日韩在线视频观看免费 | 日韩一区二区三区高清免费看看 | 在线小视频你懂得 | 亚洲天堂免费视频 | 99精品视频免费 | 国产亚洲小视频 | 国产精品久久久久久久久久三级 | 丁香av在线| 黄色网址在线播放 | 国产黄色片一级三级 | 久久久伦理 | 久久午夜网 | 美国人与动物xxxx | 激情婷婷 | 国产一二三区在线观看 | 午夜少妇一区二区三区 | 97超级碰碰| 欧美中文字幕久久 | 成人一区二区三区中文字幕 | 久久99精品久久久久久久久久久久 | 美女免费网视频 | 日韩久久久久久 | 97偷拍视频| 香蕉视频久久久 | 国产精品中文字幕在线观看 | 久久久久综合视频 | 日韩免费高清在线观看 | 国产伦精品一区二区三区照片91 | 久久视频免费在线 | 成人黄色大片在线观看 | 色综合久久中文综合久久牛 | 国产 日韩 欧美 在线 | 中文字幕成人网 | 欧美日韩中文在线 | 黄色免费观看 | 日韩久久久久久久 | 午夜精品久久久 | 99久久精品无码一区二区毛片 | 亚洲成人av在线 | www操操操| 黄色一级大片在线免费看国产一 | 欧美男同网站 | 国产精品大尺度 | 中文字幕日本在线观看 | 免费激情在线电影 | 国产精品99久久免费黑人 | 国产精品18久久久久久久网站 | 国产精品去看片 | 精品国模一区二区三区 | 美女黄频 | 九九综合久久 | 正在播放 国产精品 | 亚洲成人午夜在线 | 免费高清男女打扑克视频 | 美女视频a美女大全免费下载蜜臀 | 一区二区精品久久 | 中文字幕日韩国产 | 国产视频 亚洲视频 | 福利片视频区 | 欧美精品在线观看 | 国产精品自产拍在线观看 | 波多野结衣精品 | 成人久久 | 国产精品久久久久久a | 国产精品一区一区三区 | 成年在线观看 | 成人av电影免费 | av中文国产 | 中文日韩在线 | 国产九九精品视频 | 婷婷综合在线 | 99热精品国产一区二区在线观看 | 中文字幕高清在线播放 | 日本中文字幕在线 | 免费久久久久久久 | 亚洲激情视频在线 | 九九视频这里只有精品 | 婷婷亚洲五月色综合 | 999成人 | 国产在线精品观看 | 涩涩伊人| 欧美成人按摩 | www成人精品| 亚洲va男人天堂 | 亚州中文av| 五月婷婷综合在线观看 | 精品夜夜嗨av一区二区三区 | 精品久久久久久久久中文字幕 | 免费看黄电影 | 国产成人三级在线 | 欧美在线观看视频一区二区 | 日韩在线高清 | 色综合久久精品 | av网站播放 | av资源免费在线观看 | 午夜成人免费影院 | 97在线精品 | zzijzzij日本成熟少妇 | 久久精品久久99 | 免费在线一区二区三区 | 欧美日韩免费在线观看视频 | 国产免费人成xvideos视频 | 国产自产高清不卡 | 色偷偷中文字幕 | 91丨九色丨蝌蚪丨对白 | 婷婷黄色片 | 就操操久久| 久久久久久久综合色一本 | 激情开心网站 | 91成人免费观看视频 | 国产精品99久久久精品免费观看 | 不卡中文字幕av | 成人黄色免费观看 | 国产精品久久久久久久免费大片 | 国产精品免费久久久 | 国产精品久久久久一区 | 开心激情五月婷婷 | 精品一区二区免费在线观看 | 国产精品岛国久久久久久久久红粉 | 国产精品自产拍在线观看 | www麻豆视频 | www.夜夜| 最近日本字幕mv免费观看在线 | 国产在线黄 | 久久综合五月天婷婷伊人 | 久久久久久免费 | av在线之家电影网站 | 五月视频 | 欧日韩在线 | 一区二区三区免费播放 | 日韩av电影免费在线观看 | 精品在线播放视频 | 亚洲精品免费观看 | 少妇搡bbb | av怡红院| 国产一区二区三区高清播放 | 91毛片在线| 国产夫妻性生活自拍 | 97夜夜澡人人爽人人免费 | 操高跟美女 | 天天操比| 天天干天天操天天拍 | 免费观看一级一片 | 激情视频亚洲 | 国产成人精品久久 | 狠狠色伊人亚洲综合成人 | 97电影手机 | 婷婷色综合色 | 波多野结衣电影一区二区三区 | 婷婷丁香激情综合 | 99一区二区三区 | 日韩欧美一区二区三区视频 | 狂野欧美激情性xxxx欧美 | 欧美性极品xxxx娇小 | 91久久精品一区二区三区 | 久久久资源网 | 亚洲综合色播 | 精品久久一 | 91av在线电影 | 国内精品久久久久久久久久久久 | www欧美日韩 | 午夜美女福利直播 | 成人免费在线观看电影 | 毛片3 | 碰超在线观看 | 国产美女视频网站 | 日韩中文在线字幕 | 一区二区三区www | 91av久久 | 久久最新| 天天射天天拍 | 亚洲国产影院av久久久久 | 久久久久久久久久久国产精品 | 国产伦理久久精品久久久久_ | 国产美女视频一区 | 日韩中文字幕a | 成人中文字幕在线观看 | 探花视频免费在线观看 | 97国产一区二区 | 中文在线资源 | 成人亚洲精品国产www | 国产精品午夜久久久久久99热 | 欧美色综合天天久久综合精品 | 四虎在线免费观看 | 久久久久在线观看 | 99久久er热在这里只有精品15 | 黄色软件网站在线观看 | 日韩高清成人在线 | 天天射射天天 | 日韩二三区| av中文字幕在线免费观看 | 亚洲精品午夜一区人人爽 | 亚洲精品视频在线免费播放 | 国产视频一区二区在线观看 | 在线观看视频中文字幕 | 久久精品国产免费看久久精品 | 国产精品九九热 | 日韩在线一二三区 | 国产精品久久久久久久久久ktv | 色播激情五月 | 日韩欧美一区视频 | 日韩免费看的电影 | 午夜精品在线看 | 五月天激情综合网 | 中文字幕在线视频免费播放 | 国产亚洲视频中文字幕视频 | 亚洲一区二区视频在线 | 一本到在线 | 日本天天色 | 最新国产在线视频 | 色婷婷综合久久久 | 手机看片 | 亚洲精品国产精品国自产在线 | 亚洲国内精品 | 九九在线视频免费观看 | 69夜色精品国产69乱 | www.色午夜 | 国产精品久久9 | 久久免费播放视频 | 中文字幕在线一区二区三区 | 激情五月色播五月 | 久草综合视频 | 福利电影久久 | 九七在线视频 | 国产专区免费 | 在线观看中文字幕视频 | 欧美一级日韩三级 | 成人午夜影视 | 精品天堂av| 九九亚洲精品 | 密桃av在线 | 国产精品久久久久久久久久三级 | 91麻豆网| 久久久久成人精品免费播放动漫 | 欧美日韩伦理一区 | 午夜av免费观看 | 免费看国产视频 | 成人在线视频在线观看 | 国产特黄色片 | av免费观看网站 | 人人干干人人 | 精品成人国产 | 在线播放亚洲 | 91av视频在线免费观看 | 免费观看丰满少妇做爰 | 日韩欧美视频在线 | 国产麻豆精品免费视频 | 久久久久久久久久久久久久av | 精品国产乱码久久久久久久 | 91精品啪在线观看国产 | 在线观看久久久久久 | 国产精品久久一区二区无卡 | 97超碰在线资源 | 九九视频精品在线 | 亚洲欧美国产精品久久久久 | 久久福利 | 国产亚洲精品久久久久久电影 | 免费在线中文字幕 | 亚洲精品视频久久 | 国产精品男女啪啪 | 久久在线免费视频 | 在线国产精品视频 | 国产日韩精品一区二区三区在线 | 97成人资源 | 97免费中文视频在线观看 | 免费a视频在线观看 | 免费在线91 | 国产亚洲综合在线 | 99久久久久 | 丝袜美腿在线视频 | 国产精品男女视频 | 久久a久久 | 国产成人在线观看 | 亚洲综合精品在线 | 久草视频免费在线播放 | 国产又粗又硬又长又爽的视频 | 日韩久久精品一区二区三区下载 | 黄视频网站大全 | 99久久久国产精品免费99 | 麻豆久久一区 | 国产成人免费网站 | 婷婷丁香六月天 | 操操操日日日 | 91爱看片 | 最近日本mv字幕免费观看 | 天天干天天搞天天射 | www.天天色.com | 色婷婷 亚洲 | 黄色毛片视频 | 久久综合九色综合欧美狠狠 | 免费电影一区二区三区 | 亚洲天堂网在线观看视频 | 国产精品一区二区三区久久 | 精品国产一区二区三区蜜臀 | 国产精品国产三级国产aⅴ入口 | 美女视频黄频大全免费 | 日韩精品一区二区三区在线视频 | 免费网站观看www在线观看 | 日本论理电影 | 久久精品国产一区二区电影 | 久久97精品| 欧美一区二区三区免费看 | 九九亚洲视频 | 午夜精品久久久久久久久久久 | 9免费视频 | av在线免费观看不卡 | 天天综合导航 | 人人澡澡人人 | 久久国产精品第一页 | 国产一级在线播放 | 国产91精品一区二区 | 波多野结衣最新 | 久久成年人 | 亚洲乱亚洲乱妇 | 久久久久久久久久电影 | 国产二区电影 | 中文字幕刺激在线 | 国产精品综合在线 | 成人三级视频 | 国产伦理一区二区三区 | 国产麻豆精品传媒av国产下载 | 中文字幕免费 | 成人在线免费视频 | 国产视频一二三 | 免费精品国产va自在自线 | 亚洲国产美女久久久久 | av在线进入 | 91精品资源 | 欧美一区二区在线看 | 亚洲精品综合一二三区在线观看 | 日本中文字幕观看 | 国产精品久久久久亚洲影视 | 精品久久久久久久久久 | 亚洲精品视频网 | 国产精品video爽爽爽爽 | 国产精品igao视频网入口 | 1024手机看片国产 | 免费麻豆视频 | 亚洲精品久久久蜜臀下载官网 | 国产在线久草 | 欧美日韩一级久久久久久免费看 | 久久成人国产精品免费软件 | 人人爱人人射 | 999热视频| 91在线看免费 | 国内精品久久久久久久影视麻豆 | 欧美电影在线观看 | 人人超碰在线 | 久久男人免费视频 | 九九涩涩av台湾日本热热 | 91麻豆操| 少妇高潮流白浆在线观看 | 青春草视频 | 99在线观看视频 | 欧洲精品码一区二区三区免费看 | 超碰97人人爱 | 人人看人人艹 | 成人av影院在线观看 | 中文国产成人精品久久一 | 91成人精品观看 | av成人动漫在线观看 | 亚洲欧美视屏 | 黄网站免费大全入口 | 久久精品8 | 国产高清一区二区 | 免费成人黄色片 | 99re久久资源最新地址 | 免费视频二区 | 精品国产乱码久久久久久1区二区 | 国产精品久久中文字幕 | 高清av影院 | 久久国产a | 免费看搞黄视频网站 | 操操操av | 国产精品美女网站 | 国产精品久99 | 亚洲在线成人精品 | 五月天婷婷在线观看视频 | 国内精品久久影院 | 一区二区亚洲精品 | 久久国产精品99国产精 | 69久久99精品久久久久婷婷 | 一区二区视频在线观看免费 | 成人在线视频论坛 | 热re99久久精品国产66热 | 91热在线| 国产999久久久 | 中文字幕视频网站 | 免费看黄视频 | 国产精品免费久久久久 | 国产麻豆精品一区二区 | 国产高清无线码2021 | 欧美日韩国产精品久久 | 欧美一级黄色网 | 91中文字幕在线视频 | 超碰日韩在线 | 奇米影视777影音先锋 | 五月天久久久 | 欧美日韩视频网站 | 亚洲一级黄色 | 亚洲综合导航 | 天天人人 | 午夜精品福利在线 | 欧美视频99| 在线观看国产麻豆 | 91亚洲综合 | 日韩三级.com | 97日日碰人人模人人澡分享吧 | 福利久久| 日韩欧美在线免费 | 激情电影在线观看 | 中文字幕乱码日本亚洲一区二区 | 天天综合网久久 | 在线亚州| 婷婷深爱网 | 丝袜美腿亚洲综合 | 91av在线免费看 | 成人在线观看网址 | 91在线精品一区二区 | 欧美日韩精品在线一区二区 | 国产精品乱看 | 九九免费在线视频 | 一区二区三区高清在线观看 | 免费日韩精品 | 四虎影视成人永久免费观看视频 | 久久精品视频国产 | 日韩三级不卡 | www.久久色 | 色婷婷激情网 | 青春草免费在线视频 | 一区二区伦理 | 亚洲免费不卡 | 97超碰人人干| 亚洲国产成人av网 | 久久午夜色播影院免费高清 | 亚洲天堂精品视频在线观看 | 伊人婷婷网 | 久久视频精品在线 | 91字幕| 在线免费观看视频一区二区三区 | 国产a级精品 | 欧美亚洲成人免费 | 国产成人av福利 | 亚洲综合色视频 | 亚洲美女在线一区 | av品善网| 黄色app网站在线观看 | 激情综合五月婷婷 | 99久久综合国产精品二区 | 人人看人人| 日韩精品视 | 精品久久久免费 | 亚洲少妇久久 | 天堂资源在线观看视频 | 91久草视频 | 丁香激情综合国产 | 国产中年夫妇高潮精品视频 | 中文字幕在线观看一区 | 久久久性 | 免费高清在线观看电视网站 | 在线播放国产一区二区三区 | 99国产精品久久久久老师 | 黄色免费观看网址 | 91色欧美 | 亚洲高清视频在线播放 | 91视频久久久久久 | 香蕉久久久久久久 | 精品91视频 | 亚洲精品玖玖玖av在线看 | 中文字幕在线观看第一区 | 欧美成人影音 | 毛片基地黄久久久久久天堂 | 婷婷激情五月 | 99精品国产成人一区二区 | 亚洲无吗视频在线 | 手机在线观看国产精品 | 91人人爽人人爽人人精88v | 久久不色 | 日本激情动作片免费看 | 国产视频在线观看一区二区 | 久久精品日本啪啪涩涩 | 在线免费观看视频一区 | 中文字幕在线免费看线人 | 草久在线观看视频 | 精品无人国产偷自产在线 | 91在线免费观看国产 | 欧美性色黄 | 天操夜夜操| 久久精品在线免费观看 | 国产精品一区二区三区电影 | 日韩在线三级 | 中文在线www| 国产一区国产二区在线观看 | 免费看片日韩 | 91xav| 免费成人短视频 | 美女网站视频一区 | 特黄色大片 | 国产亚洲日本 | 91日韩精品一区 | 69欧美视频 | 国内精品久久久久影院一蜜桃 | 一级片视频在线 | 日本精品一区二区三区在线播放视频 | 在线观看精品视频 | 黄色亚洲免费 | 成人黄大片视频在线观看 | 国产小视频在线播放 | 国产精品理论在线观看 | 日日爱999| 久久久久激情视频 | 九九视频免费在线观看 | 天天曰天天干 | 午夜精品一区二区三区在线 | 99情趣网视频| 天天操天天操一操 | 夜夜躁狠狠躁日日躁视频黑人 | 日韩电影中文,亚洲精品乱码 | 在线黄色国产电影 | 国产日韩精品一区二区在线观看播放 | 97人人模人人爽人人喊中文字 | 亚洲电影在线看 | 91高清视频在线 | 在线观看播放av | 91成人久久 | 国产精品第一视频 | 国产一区网| 麻豆精品传媒视频 | 亚洲精品中文字幕视频 | 国产资源免费在线观看 | 国产涩图| 精品国产人成亚洲区 | 亚洲精区二区三区四区麻豆 | 国产特级毛片 | 91视频啪 | 麻豆91精品 | 日韩精品在线观看视频 | 色综合久久久久久久 | 日韩超碰 | 五月婷婷电影网 | 国产精品成人一区二区三区吃奶 | 国产亚洲婷婷免费 | 欧美一级日韩免费不卡 | 亚洲欧美国产日韩在线观看 | 亚洲精区二区三区四区麻豆 | 日韩 在线观看 | 久久久久国产免费免费 | 久久成人国产精品免费软件 | 免费av黄色| 中文乱幕日产无线码1区 | 久久精品国产精品亚洲 | 久草网站 | 九七视频在线观看 | 国产一在线精品一区在线观看 | 久久成人视屏 | 天堂在线免费视频 | 91精品久久久久久久久 | 日韩精品视频在线免费观看 | av高清一区| 天天操伊人 | 国产精品aⅴ | 99热在线看| 国产一区久久久 | 日韩av在线小说 | 成人aaa毛片 | 天天激情综合 | 国产精品视频最多的网站 | 国产中文字幕一区二区 | 四虎影视成人永久免费观看亚洲欧美 | 综合久久精品 | 在线不卡a| 亚洲久草在线视频 | 婷婷夜夜| 香蕉视频免费在线播放 | 国产精品高清一区二区三区 | 久久综合9988久久爱 | av播放在线| 成年人在线看片 | 日韩久久视频 | 日韩视频在线观看视频 | 视频一区在线播放 | 国产精品久久免费看 | 激情久久久久 | 国产v在线播放 | 久久黄色小说视频 | 国产日韩在线一区 | 97超碰在 | av高清不卡 | 亚洲禁18久人片 | 日韩试看| 亚洲激情六月 | 香蕉网在线播放 | 国产视频高清 | 亚州精品成人 | 蜜臀aⅴ国产精品久久久国产 | 国产最新91 | 亚洲精品久久久久中文字幕二区 | 精品在线你懂的 | 999成人 | 久久涩涩网站 | 国产精品久久久久久99 | 五月激情视频 | 婷婷五情天综123 | 久久久综合色 | 97在线观看视频免费 | 欧美做受xxx | 91在线精品视频 | 天天操操操操操操 | 久久影视网| 久久久久久久免费看 | 69视频国产 | 一区二区av | 精品国产乱码久久久久久1区2匹 | 午夜精品一区二区三区免费 | 精品成人网 | 97在线视频免费 | 欧美视屏一区二区 | 久久久国产精华液 | 偷拍福利视频一区二区三区 | 亚洲美女免费精品视频在线观看 | 91视频高清 | 天天综合亚洲 | 国产精品成人aaaaa网站 | 97日日碰人人模人人澡分享吧 | 亚洲欧洲中文日韩久久av乱码 | 久人人| 国产高清不卡一区二区三区 | 日韩欧美视频在线 | 狠狠干婷婷 | 手机av永久免费 | 精品一区在线看 | 这里只有精品视频在线观看 | 久久久久久国产精品美女 | 国产高清福利在线 | 五月天色网站 | 亚洲三级性片 | 成人a在线观看高清电影 | 九九热视频在线免费观看 | 亚洲国产精品成人va在线观看 | 色婷婷狠 | 免费黄在线观看 | 亚洲国产中文字幕在线 | 黄色1级毛片 | 欧美精彩视频 | 99视频在线 | 国产高清区 | 精品视频久久 | av大片免费在线观看 | 国内精品久久久久久中文字幕 | 亚洲jizzjizz日本少妇 | 久久丁香 | 日韩影视精品 | 天天操天天添 | 国产精品永久在线观看 | 五月婷婷一级片 | 免费看黄色小说的网站 | 国产美女主播精品一区二区三区 | 久久手机在线视频 | 久草电影在线 | 少妇激情久久 | 日韩欧美一区二区三区免费观看 | 精品久久久久亚洲 | 成人av教育| 免费视频黄色 | 激情丁香5月 | 久久综合视频网 | 五月开心六月伊人色婷婷 | 人人搞人人干 | 1024手机基地在线观看 | 欧美性生交大片免网 | 91丨porny丨九色| 欧美日韩1区2区 | 成年人免费在线观看网站 | 国产91精品一区二区绿帽 | 色偷偷88888欧美精品久久久 | 国产剧情一区 | 99九九热只有国产精品 | www日韩在线观看 | 国产手机av| 亚洲电影成人 | 亚洲第一区在线观看 | 欧美精彩视频在线观看 | 久久伊人八月婷婷综合激情 | 色综合天天视频在线观看 | 精品视频不卡 | 久久精品亚洲一区二区三区观看模式 | 999国内精品永久免费视频 | 久久久久免费电影 | 亚洲午夜激情网 | 日韩精品免费一区二区 | 免费观看国产成人 | 国产精品欧美久久久久无广告 | 日韩在线观看视频免费 | 色悠悠久久综合 | 丁香九月激情综合 | 天堂网av在线 | 精品人妖videos欧美人妖 | 中文字幕a∨在线乱码免费看 | 天天操天天曰 | 亚洲精品免费在线播放 | 在线 精品 国产 | 亚洲午夜不卡 | 丁香国产视频 | 91视频高清| 亚洲国内精品在线 | 456免费视频 | 午夜视频在线观看一区二区 | 欧美视频xxx | 在线播放视频一区 | 久久视频精品在线观看 | 久久精品婷婷 | 99r在线精品| 国产偷国产偷亚洲清高 | www.狠狠干| 久久久99精品免费观看app | 黄色在线看网站 | 日本久久久久久 | 毛片网站在线观看 | 狠狠色丁香婷婷综合久久片 | 亚洲精品在线免费看 | 久久精品视频在线免费观看 | 成人免费影院 | 免费看一级黄色大全 | 超碰97人人爱 | 日韩欧美在线国产 | 成 人 黄 色 视频播放1 | 亚洲毛片一区二区三区 | 国产色视频123区 | 日本在线观看一区二区三区 | av免费网| 日韩成人免费在线观看 | 亚洲精品免费在线观看视频 | 国产一区二区影院 | 国产专区精品视频 | 中文字幕第一页在线播放 | 黄色软件大全网站 | 国精产品999国精产品岳 | 欧美美女一级片 | 福利一区在线 | 69国产成人综合久久精品欧美 | 噜噜色官网| 一级片免费观看视频 | 97在线观看免费高清完整版在线观看 | 国产高清专区 | 亚洲自拍偷拍色图 | 99视频精品视频高清免费 | 国产一区二区网址 | 丁香六月婷婷开心婷婷网 | 国产69精品久久久久久久久久 | 精品国产视频在线 | 99综合久久 | 99riav1国产精品视频 | 干 操 插 | 黄色一级免费 | 日韩一级黄色大片 | 国产午夜三级一区二区三 | aaa日本高清在线播放免费观看 | 精品一区二区三区久久 | 亚洲国产免费看 | 天天爱天天草 | 欧美性视频网站 | 亚洲国产成人高清精品 | 久久国产精品99久久久久久老狼 | 日本韩国欧美在线观看 | 91污污视频在线观看 | 成年人免费看 | 99超碰在线播放 | 在线视频免费观看 | 国产精品99久久久久久宅男 | 免费亚洲片 | 欧美日韩一级久久久久久免费看 | 日韩av在线影视 | 久久人视频 | 色爱区综合激月婷婷 | 国产一区二区久久久久 | 欧美一区二区三区在线播放 | 亚洲成人av在线 | 欧美精品一区在线发布 | 色av男人的天堂免费在线 | 五月婷婷中文字幕 | 欧美一级电影在线观看 | 91视频 - 114av | 亚洲国产视频在线 | 久久精品久久久精品美女 | 国产精品一区二区在线播放 | 久色免费视频 | 欧亚日韩精品一区二区在线 | 成人av直播| 亚洲视频免费在线观看 | 久久久国产精品麻豆 | 日日夜夜天天久久 | 超级碰碰免费视频 | 在线观看成人小视频 | 色婷婷国产精品 | 国产在线精品视频 | 黄色在线观看免费网站 | 少妇搡bbb| 岛国一区在线 | 天天综合网天天综合色 | 国产精品99爱 | av中文字幕电影 | 久草视频一区 | 狠狠天天 | 中文字幕中文中文字幕 | 国产69精品久久久久久 | 97成人精品区在线播放 | 在线观看理论 | 一区av在线播放 | 国产在线高清 | 午夜一级免费电影 | 久久久久电影网站 | 天天操天天干天天爽 | 日日夜夜人人天天 | 少妇bbb搡bbbb搡bbbb′ | 国产日韩中文在线 | 99在线看 | av黄色av| 夜夜爽夜夜操 | 中文在线字幕观看电影 | 亚州人成在线播放 | 国模精品一区二区三区 | 97超级碰 | 91亚洲欧美激情 | 免费观看一区二区 | 欧美性大战久久久久 | 麻豆视频免费在线观看 | 免费观看一区二区三区视频 | 久久久久国产精品厨房 | 久久天天躁夜夜躁狠狠85麻豆 | 99久久精品电影 | 色欲综合视频天天天 | 中文字幕亚洲精品在线观看 | 久久免费黄色网址 | 中文字幕永久在线 | 亚洲涩涩色 | 高清av中文字幕 | 国产精品mv | 欧美日韩一区二区在线观看 | 伊人色综合久久天天 | 婷婷综合 | 国产 日韩 欧美 在线 | 国产97在线观看 | 日本精品中文字幕在线观看 | 在线观看视频色 | 激情五月婷婷 | 丁五月婷婷 | 丁香五婷 | 亚洲日本一区二区在线 | 精品在线免费视频 | 五月婷婷视频在线 | 成人三级网站在线观看 | 狠狠干在线播放 | 国产五十路毛片 | 插综合网| 四虎在线影视 | 豆豆色资源网xfplay | 日韩免费福利 | 免费看色的网站 | www狠狠操| 婷婷亚洲综合五月天小说 | 日本精品视频在线观看 | 亚洲婷婷在线视频 | 亚洲国产免费看 | 国语麻豆 | 日韩电影中文,亚洲精品乱码 | 福利视频网站 | 成人黄大片视频在线观看 | 亚洲aⅴ免费在线观看 | 久久精品免费观看 | 久草在线这里只有精品 | 97热久久免费频精品99 | 久草电影免费在线观看 | 不卡日韩av| 国产亚洲免费的视频看 | 久久99久国产精品黄毛片入口 | 午夜 久久 tv | 91插插插网站 | 有码中文字幕 | 欧美中文字幕第一页 | 久久艹免费 | 在线不卡中文字幕播放 | 国产资源网 | 热re99久久精品国产99热 | 丁香九月激情综合 | 日本特黄一级片 | 国外av在线 | 久久99精品久久久久蜜臀 | 九九热免费在线观看 | 免费在线观看a v | 亚洲高清精品在线 | 国产精品午夜在线 | av在线激情 |