C++中常用關(guān)鍵字詳解(3)

2023-08-08 16:22:52 來源:Linux兵工廠

位域

C++中,位域(bit fields)是一種特殊的數(shù)據(jù)結(jié)構(gòu),允許將結(jié)構(gòu)體或類的成員變量按位進(jìn)行分配。通過位域,可以有效地利用內(nèi)存,節(jié)省存儲(chǔ)空間,特別適用于表示布爾類型、標(biāo)志位或其他不需要完整字節(jié)的數(shù)據(jù)。


(資料圖)

位域的語法格式如下:

struct MyStruct {    dataType memberName : numBits;};

其中,dataType是要存儲(chǔ)的數(shù)據(jù)類型,memberName是位域成員的名稱,numBits是分配給該成員的位數(shù)。numBits表示該成員所占用的位數(shù),必須是正整數(shù),不能超過數(shù)據(jù)類型的位數(shù)。

以下是一個(gè)簡(jiǎn)單的例子,演示了C++類中位域的使用:

#include < iostream >class MyFlags {public:    MyFlags() : isRed(0), isGreen(0), isBlue(0) {}    // 位域成員    unsigned int isRed : 1;    unsigned int isGreen : 1;    unsigned int isBlue : 1;};int main() {    MyFlags myFlags;    myFlags.isRed = 1;    myFlags.isGreen = 0;    myFlags.isBlue = 1;    std::cout < < "Size of MyFlags: " < < sizeof(MyFlags) < < " bytes" < < std::endl;    std::cout < < "isRed: " < < myFlags.isRed < < std::endl;    std::cout < < "isGreen: " < < myFlags.isGreen < < std::endl;    std::cout < < "isBlue: " < < myFlags.isBlue < < std::endl;    return 0;}

輸出可能為:

Size of MyFlags: 4 bytesisRed: 1isGreen: 0isBlue: 1

在上述示例中,我們定義了一個(gè)名為MyFlags的類,其中包含三個(gè)位域成員isRed、isGreen和isBlue,每個(gè)成員都占用1位。由于unsigned int通常是4字節(jié)(32位),所以類MyFlags的大小為4字節(jié)。

在使用類中的位域時(shí),需要注意類的成員訪問權(quán)限以及可能的內(nèi)存對(duì)齊問題。位域成員只能是整數(shù)類型或枚舉類型,并且不支持引用。類中的位域成員也受到相同的限制,不能超過其數(shù)據(jù)類型的位數(shù)。

使用位域時(shí)應(yīng)該謹(jǐn)慎考慮,確保了解位域的特性和限制,并在適當(dāng)?shù)那闆r下使用它們,以提高內(nèi)存利用效率。在需要移植性和可靠性的場(chǎng)景中,建議使用常規(guī)的數(shù)據(jù)成員而不是位域

extern “C”

在C++中,extern "C"是一個(gè)用于聲明C語言風(fēng)格的函數(shù)和變量的關(guān)鍵字。C++與C在編譯和鏈接過程中有一些差異,其中包括名稱修飾(name mangling)和函數(shù)重載等特性。使用extern "C"可以告訴C++編譯器將某些函數(shù)和變量按照C語言的規(guī)則進(jìn)行處理,以實(shí)現(xiàn)C和C++之間的混合編程

使用extern "C"有以下幾個(gè)常見的場(chǎng)景:

C++調(diào)用C語言庫:當(dāng)C++代碼需要調(diào)用一個(gè)由C語言編寫的庫時(shí),由于C和C++之間的名稱修飾不同,需要使用extern "C"來正確鏈接C語言的函數(shù)。C語言調(diào)用C++函數(shù):當(dāng)C語言代碼需要調(diào)用一個(gè)由C++編寫的函數(shù)時(shí),由于C++可能存在函數(shù)重載和其他特性,需要使用extern "C"來告訴C語言編譯器按照C語言的方式處理函數(shù)。

以下是一些示例,說明了extern "C"的用法:

C++調(diào)用C語言庫的示例:C++代碼(main.cpp):

#include < iostream >extern "C" {    void c_function(); // 聲明C語言風(fēng)格的函數(shù)}int main() {    c_function(); // 調(diào)用C語言風(fēng)格的函數(shù)    return 0;}

C語言代碼(c_library.c):

#include < stdio.h >void c_function() {    printf("This is a C function.n");}

C語言調(diào)用C++函數(shù)的示例: C++代碼(cpp_library.cpp):

#include < iostream >extern "C" {    void cpp_function(); // 聲明C語言風(fēng)格的函數(shù)}void cpp_function() {    std::cout < < "This is a C++ function." < < std::endl;}

C語言代碼(main.c):

extern void cpp_function(); // 聲明C語言風(fēng)格的函數(shù)int main() {    cpp_function(); // 調(diào)用C++函數(shù)    return 0;}

在上述示例中,我們通過使用extern "C"關(guān)鍵字來正確地鏈接C和C++之間的函數(shù)。

需要注意的是,extern "C"應(yīng)該只用于C和C++之間的函數(shù)和全局變量的聲明,而不應(yīng)該用于類的定義和成員函數(shù)。因?yàn)轭惖某蓡T函數(shù)涉及到C++的特性,無法通過簡(jiǎn)單的名稱修飾解決鏈接問題。在需要使用C++類的情況下,可以考慮提供一個(gè)純C接口來實(shí)現(xiàn)交互。

struct

在C++中,struct是用于定義自定義數(shù)據(jù)類型的關(guān)鍵字,它是一種用戶定義的數(shù)據(jù)結(jié)構(gòu),可以包含不同類型的成員變量和成員函數(shù)。struct與class非常相似,但有一些不同之處。

以下是關(guān)于C++中struct的一些詳解:

成員變量:struct可以包含不同類型的成員變量,這些成員變量默認(rèn)是public(公共)訪問權(quán)限的。這意味著結(jié)構(gòu)體的成員可以從外部直接訪問和修改。
struct MyStruct {     int x;  // 公共成員變量,默認(rèn)訪問權(quán)限是 public     double y; // 公共成員變量,默認(rèn)訪問權(quán)限是 public};
成員函數(shù):struct可以定義成員函數(shù),用于操作和訪問結(jié)構(gòu)體的成員變量。
struct MyStruct {    int x;    void printX()     {        std::cout < < "x = " < < x < < std::endl;    }};
繼承:struct可以通過繼承派生出子結(jié)構(gòu)體。派生類繼承了基類的成員和方法。
struct Base  {     int x; }; struct Derived : Base  {     double y; };
構(gòu)造函數(shù)和析構(gòu)函數(shù):struct可以定義構(gòu)造函數(shù)和析構(gòu)函數(shù),用于對(duì)象的初始化和資源的清理。
struct MyStruct {     int x;     // 構(gòu)造函數(shù)     MyStruct(int value)      {         x = value;     }     // 析構(gòu)函數(shù)     ~MyStruct()      {         std::cout < < "MyStruct object destroyed." < < std::endl;     } };
類型別名:struct可以使用typedef來定義類型別名。
struct MyStruct {    typedef int MyInt; // 定義類型別名 MyInt    MyInt x;};

需要注意的是,盡管struct和class都可以用來定義自定義數(shù)據(jù)類型,但它們有一些細(xì)微的差別:

在struct中,默認(rèn)的成員訪問權(quán)限是 public,而在class中,默認(rèn)的成員訪問權(quán)限是 private。對(duì)于結(jié)構(gòu)體,默認(rèn)繼承權(quán)限是 public,而對(duì)于類,默認(rèn)繼承權(quán)限是 private。在語法上,類可以使用class關(guān)鍵字或struct關(guān)鍵字來定義,而struct只能用于定義結(jié)構(gòu)體。除了默認(rèn)的訪問權(quán)限和默認(rèn)繼承權(quán)限之外,struct和class在其他方面幾乎是相同的。使用哪個(gè)關(guān)鍵字取決于編程風(fēng)格和設(shè)計(jì)選擇。

union

在C++中,union是一種特殊的數(shù)據(jù)結(jié)構(gòu),允許在相同的內(nèi)存位置存儲(chǔ)不同的數(shù)據(jù)類型。union的所有成員共享相同的內(nèi)存空間,這使得union在一些特定情況下非常有用,例如節(jié)省內(nèi)存或進(jìn)行類型轉(zhuǎn)換。

union的語法如下:

union UnionName {    dataType member1;    dataType member2;};

其中,UnionName是union的名稱,dataType是要存儲(chǔ)在union中的數(shù)據(jù)類型。union的成員可以是不同類型的變量,但是所有成員共享同一塊內(nèi)存,只有一個(gè)成員可以被賦值。在任何時(shí)候,union中只有一個(gè)成員的值是有效的,而其他成員的值將是未定義的。

以下是一個(gè)簡(jiǎn)單的示例,演示了union的用法:

#include < iostream >union MyUnion {    int intValue;    double doubleValue;    char charValue;};int main() {    MyUnion u;    u.intValue = 42;    std::cout < < "intValue: " < < u.intValue < < std::endl;    u.doubleValue = 3.14;    std::cout < < "doubleValue: " < < u.doubleValue < < std::endl;    u.charValue = "A";    std::cout < < "charValue: " < < u.charValue < < std::endl;    // 輸出最后設(shè)置的成員值    std::cout < < "intValue after charValue assignment: " < < u.intValue < < std::endl;    return 0;}

輸出可能為:

intValue: 42doubleValue: 3.14charValue: AintValue after charValue assignment: 65

在上述示例中,我們定義了一個(gè)union MyUnion,它有三個(gè)成員intValue、doubleValue和charValue,分別是int、double和char類型。我們可以在不同的時(shí)間點(diǎn)給union的不同成員賦值。由于union的成員共享同一塊內(nèi)存,最后賦值的成員的值會(huì)覆蓋之前的值。

C++中除此之外的特性還有:

默認(rèn)訪問控制符為 public可以含有構(gòu)造函數(shù)、析構(gòu)函數(shù)不能含有引用類型的成員不能繼承自其他類,不能作為基類不能含有虛函數(shù)匿名 union 在定義所在作用域可直接訪問 union 成員匿名 union 不能包含 protected 成員或 private 成員全局匿名聯(lián)合必須是靜態(tài)(static)的
#include< iostream >union UnionTest {    UnionTest() : i(1) {};    int i;    double j;};static union {    int i;    double j;};int main() {    UnionTest u;    union     {        int i;        double j;    };    std::cout < < u.i < < std::endl; // 輸出 UnionTest 聯(lián)合的 1    ::i = 2;    std::cout < < ::i < < std::endl; // 輸出全局靜態(tài)匿名聯(lián)合的 2    i = 3;    std::cout < < i < < std::endl; // 輸出局部匿名聯(lián)合的 3    return 0;}

需要特別注意的是,使用union需要非常小心,因?yàn)樗男袨槿菀讓?dǎo)致難以預(yù)料的結(jié)果。由于union沒有記錄當(dāng)前存儲(chǔ)的數(shù)據(jù)類型,所以在使用時(shí)需要確保正確理解其成員的含義,并避免出現(xiàn)未定義行為。一般來說,union應(yīng)該在需要特殊的內(nèi)存布局和節(jié)省內(nèi)存時(shí)才使用,并且應(yīng)該小心處理其中的數(shù)據(jù)。在現(xiàn)代C++編程中,更傾向于使用std::variant或std::any等類型安全的替代方案。

標(biāo)簽:

上一篇:開關(guān)電源的工作原理 反激式轉(zhuǎn)換器和正激式轉(zhuǎn)換器講解
下一篇:最后一頁