亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++虛函數(shù)表與類的內(nèi)存分布深入分析理解

 更新時(shí)間:2022年08月08日 15:11:24   作者:戀戀風(fēng)辰  
對(duì)C++ 了解的人都應(yīng)該知道虛函數(shù)(Virtual Function)是通過(guò)一張?zhí)摵瘮?shù)表(Virtual Table)來(lái)實(shí)現(xiàn)的。簡(jiǎn)稱為V-Table。本文就將詳細(xì)講講虛函數(shù)表的原理與使用,需要的可以參考一下

不可定義為虛函數(shù)的函數(shù)

類的靜態(tài)函數(shù)和構(gòu)造函數(shù)不可以定義為虛函數(shù):

靜態(tài)函數(shù)的目的是通過(guò)類名+函數(shù)名訪問(wèn)類的static變量,或者通過(guò)對(duì)象調(diào)用staic函數(shù)實(shí)現(xiàn)對(duì)static成員變量的讀寫,要求內(nèi)存中只有一份數(shù)據(jù)。而虛函數(shù)在子類中重寫,并且通過(guò)多態(tài)機(jī)制實(shí)現(xiàn)動(dòng)態(tài)調(diào)用,在內(nèi)存中需要保存不同的重寫版本。

構(gòu)造函數(shù)的作用是構(gòu)造對(duì)象,而虛函數(shù)的調(diào)用是在對(duì)象已經(jīng)構(gòu)造完成,并且通過(guò)調(diào)用時(shí)動(dòng)態(tài)綁定。動(dòng)態(tài)綁定是因?yàn)槊總€(gè)類對(duì)象內(nèi)部都有一個(gè)指針,指向虛函數(shù)表的首地址。而且虛函數(shù),類的成員函數(shù),static成員函數(shù)都不是存儲(chǔ)在類對(duì)象中,而是在內(nèi)存中只保留一份。

將析構(gòu)函數(shù)定義為虛函數(shù)的作用

類的構(gòu)造函數(shù)不能定義為虛函數(shù),析構(gòu)函數(shù)可以定義為虛函數(shù),這樣當(dāng)我們delete一個(gè)指向子類對(duì)象的基類指針時(shí)可以達(dá)到調(diào)用子類析構(gòu)函數(shù)的作用,從而動(dòng)態(tài)釋放內(nèi)存。

如下我們先定義一個(gè)基類和子類

class VirtualTableA
{
public:
    virtual ~VirtualTableA()
    {
        cout << "Desturct Virtual Table A" << endl;
    }
    virtual void print()
    {
        cout << "print virtual table A" << endl;
    }
};
class VirtualTableB : public VirtualTableA
{
public:
    virtual ~VirtualTableB()
    {
        cout << "Desturct Virtual Table B" << endl;
    }
    virtual void print();
};
void VirtualTableB::print()
{
    cout << "this is virtual table B" << endl;
}

我們寫一個(gè)函數(shù)做測(cè)試

void destructVirtualTable()
{
    VirtualTableA *pa = new VirtualTableB();
    useTable(pa);
    delete pa;
}
void useTable(VirtualTableA *pa)
{
    //實(shí)現(xiàn)動(dòng)態(tài)調(diào)用
    pa->print();
}

程序輸出

this is virtual table B
Desturct Virtual Table B
Desturct Virtual Table A

在上面的例子中我們先在destructVirtualTable函數(shù)中new了一個(gè)VirtualTableB類型對(duì)象,并用基類VirtualTableA的指針指向了這個(gè)對(duì)象。

然后將基類指針對(duì)象pa傳遞給useTable函數(shù),這樣會(huì)根據(jù)多態(tài)原理調(diào)用VirtualTableB的print函數(shù),然后再執(zhí)行delete pa操作。

此時(shí)如果pa的析構(gòu)函數(shù)不寫成虛函數(shù),那么就只會(huì)調(diào)用VirtualTableA的析構(gòu)函數(shù),不會(huì)調(diào)用子類VirtualTableB的析構(gòu)函數(shù),導(dǎo)致內(nèi)存泄露。

而我們將析構(gòu)函數(shù)寫成虛析構(gòu)之后,可以看到先調(diào)用了子類VirtualTableB的析構(gòu)函數(shù),再調(diào)用了基類VirtualTableA的析構(gòu)函數(shù),達(dá)到了釋放子類空間的目的。

有人會(huì)問(wèn)?將析構(gòu)函數(shù)不寫為虛函數(shù),直接delete子類對(duì)象VirtualTableB,調(diào)用子類的析構(gòu)函數(shù)不可以嗎?比如,如下的調(diào)用

    VirtualTableB *pb = new VirtualTableB();
    delete pa;

上述調(diào)用沒(méi)有問(wèn)題,無(wú)論析構(gòu)函數(shù)是否為虛析構(gòu)都可以成功釋放子類空間。但是項(xiàng)目編程中常常會(huì)編寫一些通用接口,比如上面的useTable函數(shù),

它只接受VirtualTableA類型的指針,所以我們常常會(huì)用基類指針接受子類對(duì)象來(lái)通過(guò)多態(tài)的方式調(diào)用子類函數(shù),為了方便delete基類指針也要釋放子類空間,

就要將析構(gòu)函數(shù)設(shè)置為虛函數(shù)。

虛函數(shù)表原理

為了介紹虛函數(shù)表原理,我們先實(shí)現(xiàn)一個(gè)基類和子類

class Baseclass
{
public:
    Baseclass() : a(1024) {}
    virtual void f() { cout << "Base::f" << endl; }
    virtual void g() { cout << "Base::g" << endl; }
    virtual void h() { cout << "Base::h" << endl; }
    int a;
};
// 0 1 2 3   4 5 6 7(虛函數(shù)表空間)    8 9 10 11 12 13 14 15(存儲(chǔ)的是a)
class DeriveClass : public Baseclass
{
public:
    virtual void f() { cout << "Derive::f" << endl; }
    virtual void g2() { cout << "Derive::g2" << endl; }
    virtual void h3() { cout << "Derive::h3" << endl; }
};

一個(gè)類對(duì)象其內(nèi)存分布的基本結(jié)構(gòu)為虛函數(shù)表地址+非靜態(tài)成員變量,類的成員函數(shù)不占用類對(duì)象的空間,他們分布在一片屬于類的共有區(qū)域。

類的靜態(tài)成員函數(shù)喝成員變量不占用類對(duì)象的空間,他們分配在靜態(tài)區(qū)。

虛函數(shù)表的地址存儲(chǔ)在類對(duì)象的起始位置。所以我們利用這個(gè)原理,通過(guò)尋址的方式訪問(wèn)虛函數(shù)表里的函數(shù)

void useVitualTable()
{
    Baseclass b;
    b.a = 1024;
    cout << "sizeof b is " << sizeof(b) << endl;
    int *p = (int *)(&b);
    cout << "pointer address of vitural table " << p << endl;
    cout << "address of b is " << &b << endl;
    cout << "address of a is " << p + 2 << endl;
    cout << "address of p+1 is " << p +1 << endl;
    cout << "value of a is " << *(p + 2) << endl;
    cout << "address of vitural table" << (int *)(*p) << endl;
    cout << "sizeof int is " << sizeof(int) << endl;
    cout << "sizeof p is " << sizeof(p) << " sizeof(int*) is " << sizeof(int *) << endl;
    Func pFun = (Func)(*(int *)(*p));
    pFun();
    pFun = (Func) * ((int *)(*p) + 2);
    pFun();
    pFun = (Func)(*((int *)(*p) + 4));
    pFun();
}

上面的程序輸出

sizeof b is 16
pointer address of vitural table 0xb6fdd0
address of b is 0xb6fdd0
address of a is 0xb6fdd8
address of p+1 is 0xb6fdd4
value of a is 1024
address of vitural table0x46d890
sizeof int is 4
sizeof p is 8 sizeof(int*) is 8
Base::f
Base::g
Base::h

可以看到b的大小為16字節(jié),因?yàn)槲业臋C(jī)器是64位的,所以指針類型都占用8字節(jié),int 占用4字節(jié),但是要遵循補(bǔ)齊原則,結(jié)構(gòu)體的大小要為最大成員大小的整數(shù)倍,所以要補(bǔ)齊4字節(jié),那么8+4+4 = 16 字節(jié),關(guān)于類對(duì)象對(duì)齊和補(bǔ)齊原則稍后再詳述。

b的內(nèi)存分布如下圖

這個(gè)根據(jù)不同的機(jī)器所占的字節(jié)數(shù)不一樣,在32位機(jī)器上int為4字節(jié),虛函數(shù)表地址為4字節(jié),4+4 = 8字節(jié),這個(gè)再之后再說(shuō)明對(duì)齊和補(bǔ)齊的原則。

&b表示取b的地址,因?yàn)樘摵瘮?shù)表地址存儲(chǔ)在b的起始地址,所以&b也是虛函數(shù)表的地址的地址,我們通過(guò)int* 強(qiáng)轉(zhuǎn)是方便存儲(chǔ)b的地址,因?yàn)?4位機(jī)器指針都是8字節(jié),32位機(jī)器指針是4字節(jié)。

p為虛函數(shù)表的地址的地址,p+1具體移動(dòng)了4個(gè)字節(jié),因?yàn)閜+1移動(dòng)多少個(gè)字節(jié)取決于p所指向的數(shù)據(jù)類型int,int為4字節(jié),所以p+1在p的地址移動(dòng)四個(gè)字節(jié),p+2在p的地址移動(dòng)8個(gè)字節(jié)。

p只想虛函數(shù)表的地址,換句話說(shuō)p存儲(chǔ)的是虛函數(shù)表的地址,虛函數(shù)表地址占用8字節(jié),p+2就是從p向后移動(dòng)8字節(jié),這樣剛好找到a的地址。

那么*(p+2)就是取a的數(shù)值。

int*(*p)就是取虛函數(shù)表的地址,轉(zhuǎn)為int*是方便讀寫。

我們將b的內(nèi)存分布以及虛函數(shù)表結(jié)構(gòu)畫出來(lái)

上圖中可以看到虛函數(shù)表中存儲(chǔ)的是虛函數(shù)的地址,所以通過(guò)不斷位移虛函數(shù)表的指針就可以達(dá)到指向不同虛函數(shù)的目的。

Func pFun = (Func)(*(int *)(*p));
pFun();

*(int *)(*p)就是取出虛函數(shù)表首地址指向的虛函數(shù),再通過(guò)Func轉(zhuǎn)化為函數(shù)類型,然后調(diào)用pFun即可調(diào)用虛函數(shù)f。

所以想調(diào)用第二個(gè)虛函數(shù)g,將(int*)(*p) 加2 位移8個(gè)字節(jié)即可

 pFun = (Func) * ((int *)(*p) + 2);
 pFun();

同樣的道理調(diào)用h就不贅述了。

繼承關(guān)系中虛函數(shù)表結(jié)構(gòu)

DeriveClass繼承了BaseTest類,子類如果重寫了虛函數(shù),則子類的虛函數(shù)表中存儲(chǔ)的虛函數(shù)為子類重寫的,否則為基類的。

我們畫一下DeriveClass的虛函數(shù)表結(jié)構(gòu)

因?yàn)楹瘮?shù)f被DeriveClass重寫,所以DeriveClass的虛函數(shù)表存儲(chǔ)的是自己重寫的f。

而虛函數(shù)g和h沒(méi)有被DeriveClass重寫,所以DeriveClass虛函數(shù)表存儲(chǔ)的是基類的g和h。

另外DeriveClass虛函數(shù)表里也存儲(chǔ)了自己特有的虛函數(shù)g2和h3.

下面我們還是利用尋址的方式調(diào)用虛函數(shù)

void deriveTable()
{
    DeriveClass d;
    int *p = (int *)(&d);
    int *virtual_tableb = (int *)(*p);
    Func pFun = (Func)(*(virtual_tableb));
    pFun();
    pFun = (Func)(*(virtual_tableb + 2));
    pFun();
    pFun = (Func)(*(virtual_tableb + 4));
    pFun();
    pFun = (Func)(*(virtual_tableb + 6));
    pFun();
    pFun = (Func)(*(virtual_tableb + 8));
    pFun();
}

程序輸出

Derive::f
Base::g
Base::h
Derive::g2
Derive::h3

可見(jiàn)DeriveClass虛函數(shù)表里存儲(chǔ)的f是DeriveClass的f。

(int *)(*p)表述取出p所指向的內(nèi)存空間的內(nèi)容,p指向的正好是虛函數(shù)表的地址,所以*p就是虛函數(shù)表的地址。

因?yàn)槲覀儾恢捞摵瘮?shù)表的具體類型,所以轉(zhuǎn)為int*類型,因?yàn)橹羔樤?4位機(jī)器上都是8字節(jié),可以保證空間大小正確。

接下來(lái)就是尋址和函數(shù)調(diào)用的過(guò)程,這里不再贅述。

多重繼承的虛函數(shù)表

上面的例子我們知道,如果類有虛函數(shù),那么編譯器會(huì)為該類的實(shí)例分配8字節(jié)存儲(chǔ)虛函數(shù)表的地址。

所有繼承該類的子類也會(huì)擁有8字節(jié)的空間存儲(chǔ)自己的虛函數(shù)表地址。

多重繼承的情況就是類對(duì)象空間里存儲(chǔ)多張?zhí)摵瘮?shù)表地址。子類繼承于兩個(gè)基類,并且基類都有虛函數(shù),那么子類就有兩張?zhí)摵瘮?shù)表。

多態(tài)調(diào)用原理

當(dāng)我們通過(guò)基類指針存儲(chǔ)子類對(duì)象時(shí),調(diào)用虛函數(shù),會(huì)調(diào)用子類的實(shí)現(xiàn)版本,這叫做多態(tài)。

通過(guò)前面的實(shí)驗(yàn)和圖示,我們已經(jīng)知道如果子類重寫了基類的虛函數(shù),那么他自己的虛函數(shù)表里存儲(chǔ)的就是自己實(shí)現(xiàn)的版本。

通過(guò)基類指針存儲(chǔ)子類對(duì)象時(shí),基類指針實(shí)際指向的是子類的空間,尋址也是找到子類的虛函數(shù)表,從虛函數(shù)表中找到子類實(shí)現(xiàn)的虛函數(shù),

然后調(diào)用子類版本,從而達(dá)到多態(tài)效果。

對(duì)齊和補(bǔ)齊規(guī)則

在考察一個(gè)類對(duì)象所占空間時(shí),虛函數(shù)、成員函數(shù)(包括靜態(tài)與非靜態(tài))和靜態(tài)數(shù)據(jù)成員都是不占用類對(duì)象的存儲(chǔ)空間的。對(duì)象大小= vptr(虛函數(shù)表指針,可能不止一個(gè)) + 所有非靜態(tài)數(shù)據(jù)成員大小 + Aligin字節(jié)大?。ㄒ蕾囉诓煌木幾g器對(duì)齊和補(bǔ)齊)

對(duì)齊:類(結(jié)構(gòu)體)對(duì)象每個(gè)成員分配內(nèi)存的起始地址為其所占空間的整數(shù)倍。

補(bǔ)齊:類(結(jié)構(gòu)體)對(duì)象所占用的總大小為其內(nèi)部最大成員所占空間的整數(shù)倍。

下面我們先定義幾個(gè)類

namespace AligneTest
{
    class A
    {
    };
    class B
    {
        char ch;
        void func()
        {
        }
    };
    class C
    {
        char ch1; //占用1字節(jié)
        char ch2; //占用1字節(jié)
        virtual void func()
        {
        }
    };
    class D
    {
        int in;
        virtual void func()
        {
        }
    };
    class E
    {
        char m;
        int in;
    };
}

然后通過(guò)代碼測(cè)試他們的大小

extern void aligneTest()
{
    AligneTest::A a;
    AligneTest::B b;
    AligneTest::C c;
    AligneTest::D d;
    AligneTest::E e;
    cout << "sizeof(a): " << sizeof(a) << endl;
    cout << "sizeof(b): " << sizeof(b) << endl;
    cout << "sizeof(c): " << sizeof(c) << endl;
    cout << "sizeof(d): " << sizeof(d) << endl;
    cout << "sizeof(e): " << sizeof(e) << endl;
}

程序輸出

sizeof(a): 1
sizeof(b): 1
sizeof(c): 16
sizeof(d): 16
sizeof(e): 8

我們分別對(duì)每個(gè)類的大小做解釋

a 是A的對(duì)象,A是一個(gè)空類,編譯器為了區(qū)分不同的空類,所以為每個(gè)空類對(duì)象分配1字節(jié)的空間保存其信息,用來(lái)區(qū)別不同類對(duì)象。

b 是B的對(duì)象,因?yàn)锽中定義了一個(gè)char成員變量和func函數(shù),func函數(shù)不占用空間,所以b的大小為char的大小,也就是1字節(jié)。

c 是C的對(duì)象,因?yàn)镃中包含虛函數(shù),所以C的對(duì)象c中會(huì)分配8字節(jié)用來(lái)存儲(chǔ)虛函數(shù)表,虛函數(shù)表放在c內(nèi)存的首地址,然后是ch1,

以及ch2。假設(shè)c的起始地址為0,那么0~7字節(jié)存儲(chǔ)虛函數(shù)表地址,第8個(gè)字節(jié)是1的整數(shù)倍,所以不同對(duì)齊,第8個(gè)字節(jié)存儲(chǔ)ch1。

第9個(gè)字節(jié)是1的整數(shù)倍,所以第9個(gè)字節(jié)存儲(chǔ)ch2。那么c的大小為8 + 2 = 10, 因?yàn)檠a(bǔ)齊規(guī)則要求c的大小為最大成員大小的整數(shù)

倍,最大成員為虛函數(shù)表地址8字節(jié),所以要補(bǔ)齊6個(gè)字節(jié),10+6 = 16,所以c的大小為16字節(jié)。

其內(nèi)存分配如下圖

d 是D的對(duì)象,因?yàn)镈中包含虛函數(shù),所以D的對(duì)象d中會(huì)分配8字節(jié)空間存儲(chǔ)虛函數(shù)表地址,比如0~7字節(jié)存儲(chǔ)虛函數(shù)表地址,接下來(lái)第8個(gè)字節(jié),

因?yàn)閕nt為4字節(jié),8是4的整數(shù)倍,所以不需要對(duì)齊,第8~11字節(jié)存儲(chǔ)in,這樣d的大小變?yōu)?+4= 12, 因?yàn)楦鶕?jù)補(bǔ)齊規(guī)則需要補(bǔ)齊4字節(jié),總共

大小為16字節(jié)剛好是最大成員大小8字節(jié)的整數(shù)倍。所以d為16字節(jié)

其內(nèi)存分配圖如下

e 是E的對(duì)象,e會(huì)為m分配1字節(jié)空間,為in分配4字節(jié)空間,假設(shè)地址0存儲(chǔ)m,接下來(lái)地址1存儲(chǔ)in。

因?yàn)閷?duì)齊規(guī)則要求類(結(jié)構(gòu)體)對(duì)象每個(gè)成員分配內(nèi)存的起始地址為其所占空間的整數(shù)倍,1不是4的整數(shù)倍,所以要對(duì)齊。

對(duì)齊的規(guī)則就是地址后移找到起始地址為4的整數(shù)倍,所以要移動(dòng)3個(gè)字節(jié),在地址為4的位置存儲(chǔ)in。

那么e所占的空間就是 1(m占用) + 3(對(duì)齊規(guī)則) + 4(in占用) = 8 字節(jié)。

如下圖所示

為什么要有對(duì)齊和補(bǔ)齊

這個(gè)要從計(jì)算機(jī)CPU存取指令說(shuō)起,

上圖為32位機(jī)器內(nèi)存模型,CPU通過(guò)地址總線和數(shù)據(jù)總線尋址讀寫數(shù)據(jù)。如果是64位機(jī)器,就是8列。

通過(guò)對(duì)齊和補(bǔ)齊規(guī)則,可以一次讀取內(nèi)存中的數(shù)據(jù),不需要切割和重組,是典型的用空間換取時(shí)間的策略。

比如有如下類

class Test{
    int m;
    int b;
}

我們用Test生成了兩個(gè)對(duì)象t1和t2,他們?cè)趦?nèi)存中存儲(chǔ)如下,無(wú)色的表示t1的內(nèi)存存儲(chǔ),彩色的表示t2。

在不采用對(duì)齊和補(bǔ)齊策略的情況下

在采用對(duì)齊和補(bǔ)齊策略的情況下

可見(jiàn)不采用對(duì)齊和補(bǔ)齊策略,節(jié)省空間,但是要取三次能取完數(shù)據(jù),取出后還要切割和拼接,最后才能使用。

采用對(duì)齊和補(bǔ)齊策略,犧牲了空間換取時(shí)間,讀取四次,但是不需要切割直接可以使用。

對(duì)于64位機(jī)器,采用對(duì)齊和補(bǔ)齊策略,只需讀取兩次,每次取出的都是Test對(duì)象,效率非常高。

資源鏈接

本文模擬實(shí)現(xiàn)了vector的功能。

視頻鏈接

源碼鏈接

到此這篇關(guān)于C++虛函數(shù)表與類的內(nèi)存分布深入分析理解的文章就介紹到這了,更多相關(guān)C++虛函數(shù)表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • QT5實(shí)現(xiàn)UDP通信的示例代碼

    QT5實(shí)現(xiàn)UDP通信的示例代碼

    本文主要介紹了QT5實(shí)現(xiàn)UDP通信的示例代碼,主要使用QUdpSocket類用于實(shí)現(xiàn)UDP通信,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 簡(jiǎn)要對(duì)比C語(yǔ)言中的setgid()函數(shù)和setregid()函數(shù)

    簡(jiǎn)要對(duì)比C語(yǔ)言中的setgid()函數(shù)和setregid()函數(shù)

    這篇文章主要介紹了C語(yǔ)言中的setgid()函數(shù)和setregid()函數(shù)的簡(jiǎn)要對(duì)比,是C語(yǔ)言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-08-08
  • C語(yǔ)言全部?jī)?nèi)存操作函數(shù)的實(shí)現(xiàn)詳細(xì)講解

    C語(yǔ)言全部?jī)?nèi)存操作函數(shù)的實(shí)現(xiàn)詳細(xì)講解

    這篇文章主要介紹了C語(yǔ)言全部?jī)?nèi)存操作函數(shù)的實(shí)現(xiàn)詳細(xì)講解,作者用圖文代碼實(shí)例講解的很清晰,有感興趣的同學(xué)可以研究下
    2021-02-02
  • Linux/Manjaro如何配置Vscode的C/C++編譯環(huán)境

    Linux/Manjaro如何配置Vscode的C/C++編譯環(huán)境

    這篇文章主要介紹了Linux/Manjaro配置Vscode的C/C++編譯環(huán)境,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • C++實(shí)現(xiàn)LeetCode(14.最長(zhǎng)共同前綴)

    C++實(shí)現(xiàn)LeetCode(14.最長(zhǎng)共同前綴)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(14.最長(zhǎng)共同前綴),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Qt spdlog日志模塊的使用詳解

    Qt spdlog日志模塊的使用詳解

    在Qt應(yīng)用程序開發(fā)中,良好的日志系統(tǒng)至關(guān)重要,本文將介紹如何使用spdlog 1.5.0創(chuàng)建滿足以下要求的日志系統(tǒng),感興趣的朋友一起看看吧
    2025-04-04
  • C++掃盲篇之指針詳解

    C++掃盲篇之指針詳解

    C++中一個(gè)指針的使用就已經(jīng)讓很多人欲哭無(wú)淚,可是更不幸的是他還有指向指針的指針,這篇文章主要給大家介紹了關(guān)于C++掃盲篇之指針的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • 如何在C++中通過(guò)模板去除強(qiáng)制轉(zhuǎn)換

    如何在C++中通過(guò)模板去除強(qiáng)制轉(zhuǎn)換

    本文講解的是如何在C++中通過(guò)模板去除強(qiáng)制轉(zhuǎn)換,在編程工作中應(yīng)盡量少使用強(qiáng)制類型轉(zhuǎn)換,模板有助于我們實(shí)現(xiàn)這一目的,需要的朋友可以參考下
    2015-07-07
  • 使用C++和代理IP實(shí)現(xiàn)天氣預(yù)報(bào)的采集

    使用C++和代理IP實(shí)現(xiàn)天氣預(yù)報(bào)的采集

    在當(dāng)今的互聯(lián)網(wǎng)時(shí)代,網(wǎng)絡(luò)信息的獲取變得日益重要,天氣預(yù)報(bào)信息作為日常生活的重要參考,其獲取方式也隨著技術(shù)的發(fā)展而不斷變化,在本文中,我們將探討如何使用C++和代理IP來(lái)采集天氣預(yù)報(bào)信息,文中通過(guò)代碼講解的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • C語(yǔ)言中操作utmp文件的相關(guān)函數(shù)用法

    C語(yǔ)言中操作utmp文件的相關(guān)函數(shù)用法

    這篇文章主要介紹了C語(yǔ)言中操作utmp文件的相關(guān)函數(shù)用法,包括getutent()函數(shù)和setutent()函數(shù)以及endutent()函數(shù),需要的朋友可以參考下
    2015-08-08

最新評(píng)論