C結構體、C++結構體、C++類的區別

原文鏈接:https://www.cnblogs.com/cthon/p/9170596.html

先來說說C和C++中結構體的不同

a) C語言中的結構體不能爲空,否則會報錯

1>d:\myproject\visual studio 2013\projects\myc++\main.c(71): error C2016: C 要求一個結構或聯合至少有一個成員

b) C語言中的結構體只涉及到數據結構,而不涉及到算法,也就是說在C中數據結構和算法是分離的。換句話說就是C語言中的結構體只能定義成員變量,但是不能定義成員函數。然而在C++中既可以定義成員變量又可以定義成員函數, C++中的結構體和類體現了數據結構和算法的結合。

不過雖然C語言的結構體中不能定義成員函數,但是卻可以定義函數指針,不過函數指針本質上不是函數而是指針,所以總的來說C語言中的結構體只是一個複雜數據類型 ,只能定義成員變量,不能定義成員函數,不能用於面向對象編程。來看一個函數指針的例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

int My_Add(int a, int b)

{

    return a + b;

}

int My_Sub(int a, int b)

{

    return a - b;

}

struct  CTest

{

    int(*Add)(intint); //函數指針

    int(*Sub)(intint);

};

 

int main()

{

    struct CTest test;

    int ret = 0;

    test.Add = My_Add;

    test.Sub = My_Sub;

    ret = test.Add(3, 5);

    printf("%d", ret);

}

  

c) 比如說這個結構體吧:

1

2

3

4

5

6

7

8

9

10

11

struct  CTest

{

    char ch;

    int num;

};

int main()

{

    CTest test;

    test.num = 1;

    printf("%d", test.num);

}

 

這樣在C語言中是編譯不過去的,原因提示未定義標識符CTest。總的來說就是在C語言中結構體變量定義的時候,若爲struct 結構體名 變量名定義的時候,struct不能省略。但是在C++之中則可以省略struct。

 

再來分析C++中的結構體與類的區別:

先來說說C++中兩者的相同之處: 結構體中也可以包含函數;也可以定義public、private、protected數據成員;定義了結構體之後,可以用結構體名來創建對象。也就是說在C++當中,結構體中可以有成員變量,可以有成員函數,可以從別的類繼承,也可以被別的類繼承,可以有虛函數。總的一句話:class和struct的語法基本相同,從聲明到使用,都很相似,但是struct的約束要比class多,理論上,struct能做到的class都能做到,但class能做到的stuct卻不一定做的到。

 

再來說說兩者的區別:對於成員訪問權限以及繼承方式,class中默認的是private,而struct中則是publicclass還可以用於表示模板類型,struct則不行

注意struct是可以繼承與被繼承的,這一點有的人可能忽略了,來看一下struct中的繼承與被繼承:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

struct A

{

public:

    A(){};

    virtual void Dynamic()

    {

        cout << "A" << endl;

    }

protected:

    void fun();

private:

    int m_Data;

};

 

struct B:public A

{

public:

    virtual void Dynamic()

    {

        cout << "B" << endl;

    }

};

int main()

{

    A * pa = new B;

    pa->Dynamic();

}

  

編譯完全沒有問題。

 

總結一下就是:

概念:class和struct的語法基本相同,從聲明到使用,都很相似,但是struct的約束要比class多,理論上,struct能做到的class都能做到,但class能做到的stuct卻不一定做的到。

類型:struct是值類型,class是引用類型,因此它們具有所有值類型和引用類型之間的差異。

效率:由於堆棧的執行效率要比堆的執行效率高,但是堆棧資源卻很有限,不適合處理邏輯複雜的大對象,因此struct常用來處理作爲基類型對待的小對象,而class來處理某個商業邏輯。

關係:struct不僅能繼承也能被繼承 ,而且可以實現接口,不過Class可以完全擴展。內部結構有區別,struct只能添加帶參的構造函數,不能使用abstract和protected等修飾符,不能初始化實例字段。

拓展部分:再來看一看Java之中類和結構體的區別,來看一個例子:

代碼:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

static void Main(string[] args)

        {

            int strNumberA = 100;

            int strNumberB = strNumberA;//編譯器會先複製strNumberA的值,後賦給strNumberB,會在內存的兩個地方儲存值100

 

            MyVector vA = new MyVector();

            MyVector vB = vA;//引用變量的賦值 賦值操作完成後,兩個變量都指向同一內存地址

            vA.Value = 100;

            Console.WriteLine(vA.Value + "  等於  " + vB.Value);//由於vA和vB指向同一內存地址,所以vB.Value的值也爲100 

            vB.Value = 200;

            Console.WriteLine(vA.Value + "  等於  " + vB.Value);//同理vA.Value =vB.Value

              

            MyStruct structA = new MyStruct();

            MyStruct structB = structA; //結構是值類型 賦值操作完成後,兩個結構中的結構信息一致。注意是“結構中的信息”一致。

            structA.Value = 100;

            structB.Value = 200;

            Console.WriteLine(structA.Value + "  不等於  " + structB.Value);//同理vA.Value !=vB.Value

            Console.Read();

        }

        private class MyVector

        {

            public int Value { get; set; }

        }

        private struct MyStruct

        {

            public int Value;

        

  

例子可以看出,值類型變量的賦值操作,僅僅是2個實際數據之間的複製。而引用類型變量的賦值操作,複製的是引用,即內存地址,由於賦值後二者都指向同一內存地址,所以改變其中一個,另一個也會跟着改變。

結構體引出的問題:上面說到值類型的內存不由垃圾回收控制,作用域結束時,值類型會自行釋放,減少了託管堆的壓力,因此具有性能上的優勢。例如,通常 struct比class更高效;而引用類型的內存回收,有垃圾回收機制控制。這就引出了關於.NET內存中的堆和棧的討論 。

最後做一個小小的總結:

關於 Class性能好還是Struct性能好(換言堆性能好?還是棧性能好?) 那麼什麼時機該用呢 ,比較struct和 class的不同,我使用一下網上的一個牛人總結的比較好的一段話:

(1) 在表示諸如點、矩形等主要用來存儲數據的輕量級對象時,首選struct。
(2) 在表示數據量大、邏輯複雜的大對象時,首選class。

(3) 在表現抽象和多級別的對象層次時,class是最佳選擇 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章