国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++ 面向?qū)ο笕筇匦浴鄳B(tài)

這篇具有很好參考價值的文章主要介紹了C++ 面向?qū)ο笕筇匦浴鄳B(tài)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

?<1>主頁:我的代碼愛吃辣
??<2>知識講解:C++ 繼承
??<3>開發(fā)環(huán)境:Visual Studio 2022
??<4>前言:面向?qū)ο笕筇匦缘?,封裝,繼承,多態(tài),今天我們研究研究C++的多態(tài)。

目錄

一.多態(tài)的概念

二.多態(tài)的定義及實現(xiàn)

1.多態(tài)的構(gòu)成條件

2. 虛函數(shù)

3.虛函數(shù)的重寫

4. C++11 override 和 final

5. 重載、覆蓋(重寫)、隱藏(重定義)的對比

三. 抽象類

1.概念

2.接口繼承和實現(xiàn)繼承

四.多態(tài)的原理

1.虛函數(shù)表

2.多態(tài)的原理

3. 動態(tài)綁定與靜態(tài)綁定

?5.單繼承和多繼承關(guān)系的虛函數(shù)表

1. 單繼承中的虛函數(shù)表

2. 多繼承中的虛函數(shù)表?


C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

一.多態(tài)的概念

多態(tài)的概念:通俗來說,就是多種形態(tài),具體點就是去完成某個行為,當不同的對象去完成時會
產(chǎn)生出不同的狀態(tài)。

舉個栗子:比如買票這個行為,當普通人買票時,是全價買票;學(xué)生買票時,是半價買票;軍人
買票時是優(yōu)先買票。

再舉個栗子: 幾年前為了爭奪在線支付市場,支付寶年底經(jīng)常會做誘人的掃紅包-支付-給獎勵金的
活動。那么大家想想為什么有人掃的紅包又大又新鮮8塊、10塊...,而有人掃的紅包都是1毛,5
毛....。其實這背后也是一個多態(tài)行為。支付寶首先會分析你的賬戶數(shù)據(jù),比如你是新用戶、比如
你沒有經(jīng)常支付寶支付等等,那么你需要被鼓勵使用支付寶,那么就你掃碼金額 =random()%99;比如你經(jīng)常使用支付寶支付或者支付寶賬戶中常年沒錢,那么就不需要太鼓勵你去使用支付寶,那么就你掃碼金額 = random()%1;總結(jié)一下:同樣是掃碼動作,不同的用戶掃得到的不一樣的紅包,這也是一種多態(tài)行為。ps:支付寶紅包問題純屬瞎編,大家僅供娛樂。

C++中多態(tài)演示:

class Person
{
public:
	virtual void  buy_ticket()
	{
		cout << "這是一個成年人---->全價票" << endl;

	}
};

class Student :public Person
{
public:
	virtual void buy_ticket()
	{
		cout << "這是一個學(xué)生---->八折票" << endl;
	}
};


int main()
{
	//定義好成人對象和學(xué)生對象
	Person p;
	Student s;

	//在去買票之前他們是沒有區(qū)別的
	Person& person1 = p;
	Person& person2 = s;

	//買票的學(xué)生和成人價格不一樣
	person1.buy_ticket();
	person2.buy_ticket();
    
    return 0;
}

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

二.多態(tài)的定義及實現(xiàn)

1.多態(tài)的構(gòu)成條件

多態(tài)是在不同繼承關(guān)系的類對象,去調(diào)用同一函數(shù),產(chǎn)生了不同的行為。比如Student繼承了
Person。Person對象買票全價,Student對象買票半價。

那么在繼承中要構(gòu)成多態(tài)還有兩個條件:??????????

  1. 必須通過基類的指針或者引用調(diào)用虛函數(shù)
  2. 被調(diào)用的函數(shù)必須是虛函數(shù),且派生類必須對基類的虛函數(shù)進行重寫

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

?沒有重寫虛函數(shù):

class Person{
public:
	 void  buy_ticket(){cout << "全價票" << endl;}
};

class Student :public Person{
public:
	 void buy_ticket(){cout << "八折票" << endl;}
};

int main()
{
	
	Person p;
	Student s;
	Person& person1 = p;
	Person& person2 = s;
	
	person1.buy_ticket();
	person2.buy_ticket();
	return 0;
}

?C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

?有虛函數(shù)重寫,不是通過基類的指針或者引用調(diào)用:

class Person{
public:
	 virtual void  buy_ticket(){cout << "全價票" << endl;}
};

class Student :public Person{
public:
	 virtual void buy_ticket(){cout << "八折票" << endl;}
};

int main()
{
	Person p;
	Student s;
	
	Person person1 = p;
	Person person2 = s;
	
	person1.buy_ticket();
	person2.buy_ticket();
	return 0;
}

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

2. 虛函數(shù)

虛函數(shù):即被virtual修飾的類成員函數(shù)稱為虛函數(shù),虛函數(shù)就是為多態(tài)而出現(xiàn)的。

	//虛函數(shù)
    virtual void  buy_ticket()
	{
		cout << "這是一個成年人---->全價票" << endl;
	}

?3.虛函數(shù)的重寫

虛函數(shù)的重寫(覆蓋):派生類中有一個跟基類完全相同的虛函數(shù)(即派生類虛函數(shù)與基類虛函數(shù)的
返回值類型、函數(shù)名字、參數(shù)列表完全相同),稱子類的虛函數(shù)重寫了基類的虛函數(shù)。

注意:派生類虛函數(shù)與基類虛函數(shù)的返回值類型、函數(shù)名字、參數(shù)列表完全相同,這里要求非常嚴格,因為重寫或者是覆蓋,是函數(shù)體的重寫或者覆蓋。

注意:在重寫基類虛函數(shù)時,派生類的虛函數(shù)在不加virtual關(guān)鍵字時,雖然也可以構(gòu)成重寫(因
為繼承后基類的虛函數(shù)被繼承下來了在派生類依舊保持虛函數(shù)屬性),但是該種寫法不是很規(guī)范,不建議這樣使用。

class Person {
public:
	virtual void BuyTicket() { cout << "買票-全價" << endl; }
};
class Student : public Person {
public:
	//virtual void BuyTicket() { cout << "買票-半價" << endl; }
	void BuyTicket() { cout << "買票-半價" << endl; }
};

void Func(Person& p)
{
	p.BuyTicket();
}

int main()
{
	Person p1;
	Student p2;

	Func(p1);
	Func(p2);

	return 0;
}

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

?虛函數(shù)重寫的兩個例外:

1. 協(xié)變(基類與派生類虛函數(shù)返回值類型不同)
派生類重寫基類虛函數(shù)時,與基類虛函數(shù)返回值類型不同。即基類虛函數(shù)返回基類對象的指
針或者引用,派生類虛函數(shù)返回派生類對象的指針或者引用時,稱為協(xié)變。(了解)

class Person {
public:
	virtual Person* BuyTicket() { cout << "買票-全價" << endl; return nullptr; }
};
class Student : public Person {
public:
	virtual Student* BuyTicket() { cout << "買票-半價" << endl; return nullptr; }
};

void Func(Person& p)
{
	p.BuyTicket();
}

int main()
{
	Person p1;
	Student p2;

	Func(p1);
	Func(p2);

	return 0;
}

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

?2. 析構(gòu)函數(shù)的重寫(基類與派生類析構(gòu)函數(shù)的名字不同)

如果基類的析構(gòu)函數(shù)為虛函數(shù),此時派生類析構(gòu)函數(shù)只要定義,無論是否加virtual關(guān)鍵字,
都與基類的析構(gòu)函數(shù)構(gòu)成重寫,雖然基類與派生類析構(gòu)函數(shù)名字不同。雖然函數(shù)名不相同,
看起來違背了重寫的規(guī)則,其實不然,這里可以理解為編譯器對析構(gòu)函數(shù)的名稱做了特殊處
理,編譯后析構(gòu)函數(shù)的名稱統(tǒng)一處理成destructor。

class Person {
public:
	virtual Person* BuyTicket() { cout << "買票-全價" << endl; return nullptr; }
	virtual ~Person() { cout << "~Person()" << endl; }
};
class Student : public Person {
public:
	//virtual void BuyTicket() { cout << "買票-半價" << endl; }
	virtual Student* BuyTicket() { cout << "買票-半價" << endl; return nullptr; }
	~Student() { cout << "~Student()" << endl; }
};

int main()
{
	Person* p = new Person;
	Person* s = new Student;

	delete p;
	delete s;

	return 0;
}

4. C++11 override 和 final

1. final:修飾虛函數(shù),表示該虛函數(shù)不能再被重寫

class Car
{
public:
	virtual void Drive() final {}
};
class Benz :public Car
{
public:
	virtual void Drive() { cout << "Benz-舒適" << endl; }
};

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

?2. override: 檢查派生類虛函數(shù)是否重寫了基類某個虛函數(shù),如果沒有重寫編譯報錯。

class Car {
public:
	 void Drive() {}
};
class Benz :public Car {
public:
	virtual void Drive() override { cout << "Benz-舒適" << endl; }
};

此時基類的函數(shù)并不是虛函數(shù),所以派生類中函數(shù)沒有構(gòu)成重寫,所以此處直接報錯。

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

5. 重載、覆蓋(重寫)、隱藏(重定義)的對比??????

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

三. 抽象類

1.概念

在虛函數(shù)的后面寫上 = 0 ,則這個函數(shù)為純虛函數(shù)。包含純虛函數(shù)的類叫做抽象類(也叫接口
類),抽象類不能實例化出對象。派生類繼承后也不能實例化出對象,只有重寫純虛函數(shù),派生
類才能實例化出對象。純虛函數(shù)規(guī)范了派生類必須重寫,另外純虛函數(shù)更體現(xiàn)出了接口繼承。

抽象類就像我們我們生活一些泛型的事物,例如車,車也有油車,電車,他們都是車,但是他們的動力來源不一樣。如果只是針對車這個泛型事物沒有具體到哪一種車的時候,我們也不清楚他的動力來源是什么。

class Car
{
public:
	virtual void Drive() = 0;
};
class Benz :public Car
{
public:
	virtual void Drive()
	{
		cout << "Benz-柴油機" << endl;
	}
};
class BMW :public Car
{
public:
	virtual void Drive()
	{
		cout << "BMW-高能鋰電池" << endl;
	}
};
void Test()
{
	Car* pBenz = new Benz;
	pBenz->Drive();
	Car* pBMW = new BMW;
	pBMW->Drive();
}

int main()
{
	Test();
    return 0;
}

2.接口繼承和實現(xiàn)繼承

普通函數(shù)的繼承是一種實現(xiàn)繼承,派生類繼承了基類函數(shù),可以使用函數(shù),繼承的是函數(shù)的實
現(xiàn)。
虛函數(shù)的繼承是一種接口繼承,派生類繼承的是基類虛函數(shù)的接口,目的是為了重寫,達成
多態(tài),繼承的是接口。所以如果不實現(xiàn)多態(tài),不要把函數(shù)定義成虛函數(shù)。

四.多態(tài)的原理

1.虛函數(shù)表

這里??家坏拦P試題:sizeof(Base)是多少?

// 這里??家坏拦P試題:sizeof(Base)是多少?
class Base
{
public:
    virtual void Func1()
    {
    cout << "Func1()" << endl;
    }
private:
    int _b = 1;
};

32位下結(jié)果:

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

通過觀察測試我們發(fā)現(xiàn)b對象是8bytes,除了_b成員,還多一個__vfptr放在對象的前面(注意有些
平臺可能會放到對象的最后面,這個跟平臺有關(guān),我們此處使用的是VS2022),對象中的這個指針我們叫做虛函數(shù)表指針(v代表virtual,f代表function)。一個含有虛函數(shù)的類中都至少都有一個虛函數(shù)表指針,因為虛函數(shù)的地址要被放到虛函數(shù)表中,虛函數(shù)表也簡稱虛表。那么派生類中這個表放了些什么呢?我們接著往下分析:

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

?針對上面的代碼我們做出以下改造:

  • 我們增加一個派生類Derive去繼承Base
  • Base再增加一個虛函數(shù)Func2和一個普通函數(shù)Func3
  • Derive中重寫Func1,F(xiàn)unc2,定義一個虛函數(shù)Func3
class Base
{
public:
	virtual void Func1(){cout << "Base::Func1()" << endl;}
	virtual void Func2(){cout << "Base::Func2()" << endl;}
	virtual void Func3(){cout << "Base::Func3()" << endl;}
private:
	int _b = 1;
};
class Derive : public Base
{
public:
	virtual void Func1(){cout << "Derive::Func1()" << endl;}
	virtual void Func2(){cout << "Derive::Func2()" << endl;}
private:
	int _d = 2;
};

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

1.派生類對象d中也有一個虛表指針,d對象由兩部分構(gòu)成,一部分是父類繼承下來的成員,虛
表指針也就是存在這部分的,另一部分是自己的成員。

2.基類b對象和派生類d對象虛表是不一樣的,這里我們發(fā)現(xiàn)Func1,F(xiàn)unc2完成了重寫,所以d的虛表中存的是重寫的Derive::Func1和Derive::Func2,所以虛函數(shù)的重寫也叫作覆蓋,覆蓋就是指虛表中虛函數(shù)的覆蓋。重寫是語法的叫法,覆蓋是原理層的叫法。

3.另外Func3繼承下來后是虛函數(shù),所以放進了虛表,如果Derive::Func3沒有重寫Derive::Func3不會被放進虛表,或者Base::Func3不是虛函數(shù),不會Derive::Func3被重寫也不會放進虛表。

4.虛函數(shù)表本質(zhì)是一個存虛函數(shù)指針的指針數(shù)組,一般情況這個數(shù)組最后面放了一個nullptr(僅僅針對VS系類編譯器)。

5.總結(jié)一下派生類的虛表生成:a.先將基類中的虛表內(nèi)容拷貝一份到派生類虛表中 b.如果派生
類重寫了基類中某個虛函數(shù),用派生類自己的虛函數(shù)覆蓋虛表中基類的虛函數(shù) c.派生類自己
新增加的虛函數(shù)按其在派生類中的聲明次序增加到派生類虛表的最后。

這里還有一個童鞋們很容易混淆的問題:虛函數(shù)存在哪的?虛表存在哪的? 答:虛函數(shù)存在
虛表,虛表存在對象中。注意上面的回答的錯的。
但是很多童鞋都是這樣深以為然的。注意
虛表存的是虛函數(shù)指針,不是虛函數(shù),虛函數(shù)和普通函數(shù)一樣的,都是存在代碼段的,只是
他的指針又存到了虛表中。另外對象中存的不是虛表,存的是虛表指針。
那么虛表存在哪的
呢?實際我們?nèi)ヲ炞C一下會發(fā)現(xiàn)vs下是存在代碼段的。

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

虛表的地址和代碼區(qū)(常量區(qū))很接近。

2.多態(tài)的原理

上面分析了這個半天了那么多態(tài)的原理到底是什么?還記得這里Func函數(shù)傳Person調(diào)用的
Person::BuyTicket,傳Student調(diào)用的是Student::BuyTicket。

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

1.觀察下圖的紅色箭頭我們看到,p是指向mike對象時,p->BuyTicket在mike的虛表中找到虛
函數(shù)是Person::BuyTicket。
2. 觀察下圖的藍色箭頭我們看到,p是指向johnson對象時,p->BuyTicket在johson的虛表中
找到虛函數(shù)是Student::BuyTicket。
3. 這樣就實現(xiàn)出了不同對象去完成同一行為時,展現(xiàn)出不同的形態(tài)。
4. 反過來思考我們要達到多態(tài),有兩個條件,一個是虛函數(shù)覆蓋,一個是對象的指針或引用調(diào)
用虛函數(shù)。反思一下為什么?因為單純的使用對象直接接受,不會拷貝虛表。
5. 再通過下面的匯編代碼分析,看出滿足多態(tài)以后的函數(shù)調(diào)用,不是在編譯時確定的,是運行
起來以后到對象的中取找的。不滿足多態(tài)的函數(shù)調(diào)用時編譯時確認好的。

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

void Func(Person* p)
{
	p->BuyTicket();
}
int main()
{
	Person mike;
	Func(&mike);
	mike.BuyTicket();

	return 0;
}
// 以下匯編代碼中跟你這個問題不相關(guān)的都被去掉了
void Func(Person* p)
{
	    ...
		p->BuyTicket();
	    // p中存的是mike對象的指針,將p移動到eax中
	    001940DE ?mov ????eax, dword ptr[p]
		// [eax]就是取eax值指向的內(nèi)容,這里相當于把mike對象頭4個字節(jié)(虛表指針)移動到了edx
		001940E1 ?mov ????edx, dword ptr[eax]
		// [edx]就是取edx值指向的內(nèi)容,這里相當于把虛表中的頭4字節(jié)存的虛函數(shù)指針移動到了eax
		00B823EE ?mov ????eax, dword ptr[edx]
		// call eax中存虛函數(shù)的指針。這里可以看出滿足多態(tài)的調(diào)用,不是在編譯時確定的,是運行起來
		以后到對象的中取找的。
		001940EA ?call ????eax
		00頭1940EC ?cmp ????esi, esp
}
int main()
{
	    ...
		// 首先BuyTicket雖然是虛函數(shù),但是mike是對象,不滿足多態(tài)的條件,所以這里是普通函數(shù)的調(diào)
		用轉(zhuǎn)換成地址時,是在編譯時已經(jīng)從符號表確認了函數(shù)的地址,直接call 地址
		mike.BuyTicket();
	    00195182 ?lea ????ecx, [mike]
		00195185 ?call ????Person::BuyTicket(01914F6h)
		...
}

3. 動態(tài)綁定與靜態(tài)綁定

  1. 靜態(tài)綁定又稱為前期綁定(早綁定),在程序編譯期間確定了程序的行為,也稱為靜態(tài)多態(tài),比如:函數(shù)重載。
  2. 動態(tài)綁定又稱后期綁定(晚綁定),是在程序運行期間,根據(jù)具體拿到的類型確定程序的具體行為,調(diào)用具體的函數(shù),也稱為動態(tài)多態(tài)。
  3. 本小節(jié)之前(5.2小節(jié))買票的匯編代碼很好的解釋了什么是靜態(tài)(編譯器)綁定和動態(tài)(運行時)綁定。

?5.單繼承和多繼承關(guān)系的虛函數(shù)表

1. 單繼承中的虛函數(shù)表

需要注意的是在單繼承和多繼承關(guān)系中,下面我們?nèi)リP(guān)注的是派生類對象的虛表模型,因為基類
的虛表模型前面我們已經(jīng)看過了,沒什么需要特別研究的。我們看下面一個問題:

class Base
{
public:
	virtual void Func1(){cout << "Base::Func1()" << endl;}
	virtual void Func2(){cout << "Base::Func2()" << endl;}
	virtual void Func3(){cout << "Base::Func3()" << endl;}
private:
	int _b = 1;
};
class Derive : public Base
{
public:
	virtual void Func1(){cout << "Derive::Func1()" << endl;}
	virtual void Func2() { cout << "Derive::Func2()" << endl; }
	virtual void Func4(){cout << "Derive::Func4()" << endl;}
private:
	int _d = 2;
};
int main()
{
	Base b;
	Derive d;
	
	return 0;
}

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

?這里大家仔細就會發(fā)現(xiàn)在派生類的虛表怎么沒有Func4呢?這里是編譯器的監(jiān)視窗口故意隱藏了這
兩個函數(shù),也可以認為是他的一個小bug。那么我們?nèi)绾尾榭磀的虛表呢?下面我們使用代碼打印
出虛表中的函數(shù)。

typedef void (*VFunc)();
void Print_VFTable(VFunc table[])
{
	int i = 0;
	//虛函數(shù)表本質(zhì)是一個存虛函數(shù)指針的指針數(shù)組,
	//一般情況這個數(shù)組最后面放了一個nullptr(僅僅針對VS系類編譯器)。
	while (table[i])
	{
		printf("[%d]:%p--->", i+1, table[i]);
		table[i]();
		i++;
	}
}
int main()
{
	Base b;
	Derive d;
    //取出Derive對象的前四個字節(jié),強轉(zhuǎn)成VFunc*,即函數(shù)二級指針類型
	Print_VFTable((VFunc*)(*((int*)(&d))));
	
	return 0;
}

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

?不難看出這里應(yīng)證了我們的猜想,Derive::Func4()只是被監(jiān)視窗口隱藏了。

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

2. 多繼承中的虛函數(shù)表?

class Base1 {
public:
	virtual void func1() { cout << "Base1::func1" << endl; }
	virtual void func2() { cout << "Base1::func2" << endl; }
private:
	int b1;
};
class Base2 {
public:
	virtual void func1() { cout << "Base2::func1" << endl; }
	virtual void func2() { cout << "Base2::func2" << endl; }
private:
		int b2;
};
class Derive : public Base1, public Base2 {
public:
	virtual void func1() { cout << "Derive::func1" << endl; }
	virtual void func3() { cout << "Derive::func3" << endl; }
private:
	int d1;
};
typedef void(*VFPTR) ();
void PrintVTable(VFPTR vTable[])
{
	cout << " 虛表地址>" << vTable << endl;
	for (int i = 0; vTable[i] != nullptr; ++i)
	{
		printf(" 第%d個虛函數(shù)地址 :0X%x,->", i, vTable[i]);
		VFPTR f = vTable[i];
		f();
	}
	cout << endl;
}
int main()
{
	Derive d;
	VFPTR* vTableb1 = (VFPTR*)(*(int*)&d);
	PrintVTable(vTableb1);
	VFPTR* vTableb2 = (VFPTR*)(*(int*)((char*)&d + sizeof(Base1)));
	PrintVTable(vTableb2);
	return 0;
}

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

注意一個現(xiàn)象:

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

?C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

b2->func1();

程序在執(zhí)行這句的時候,匯編多次call,和jmp,說明編譯器堆底層進行了了多次封裝,其中封裝的原因是:

?C++ 面向?qū)ο笕筇匦浴鄳B(tài),C++,c++,開發(fā)語言

?ecx 寄存器存儲的是this指針,所以這次封裝的并且sub - 8,是為了修正this指針。文章來源地址http://www.zghlxwxcb.cn/news/detail-658131.html

到了這里,關(guān)于C++ 面向?qū)ο笕筇匦浴鄳B(tài)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包