[爆卦]struct class差異是什麼?優點缺點精華區懶人包

為什麼這篇struct class差異鄉民發文收入到精華區:因為在struct class差異這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!作者pnpncat (meow)看板C_and_CPP標題Re: [問題] struct 和 cla...


※ 引述《magic15 (小花)》之銘言:
: 想請問一下
: 如果是要表示一些有相關的變數
: 用struct或是class都可以
: 而且用法也差不多
: (如果class data member都是public)
: 如果碰到這種問題
: 大部分的人都會用哪種方式來儲存這些變數
: 謝謝
如果你的資料本身就是介面
那麼你可以選擇 struct
或者選擇 class 然後將全部資料宣告為 public
其餘情況下 你應該選擇 class 然後將所有資料都宣告為 private

什麼情況下資料本身就是介面呢?
那就是資料之間有性質相關
但是沒有相依性的時候

舉例來說
表示一個抽象的長方形
你可以這樣做

struct Rectangle {
unsigned int w;
unsigned int h;
};

你也可以為他添加成員函數計算周長

struct Rectangle {
unsigned int w;
unsigned int h;
unsigned int circumference() {return 2*(w + h);}
};



但是如果資料互相之間有相依性
你就不應該將裸露的資料當作介面了
因為這些資料可能被他人不恰當地更動
而失去了原有的相依性

例如
當你要表示一個直角座標上的長方形時
你不宜這樣做

struct Rectangle {
int leftX;
int rightX;
int bottomY;
int topY;
};

不應該這樣做的原因是.......
假如有人無意間將 leftX 設為一個比 rightX 還大的值
不只是語意不符而已
基於這個 struct 設計的其他演算可能因此而失效或敗壞
例如某個演算法可能會依序巡訪從 leftX 到 rightX 的所有作標點
如果 leftX 實際上大於 rightX
那電腦就陷入無窮迴圈中了............

所以你應該這樣做

class Rectangle {
public:
int leftX() {return leftX_;}
int rightX() {return rightX_;}
int bottomY() {return bottomY_;}
int topY() {return topY_;}
void setRangeX(int x1, int x2) {
if (x1 <= x2) {
leftX_ = x1;
rightX_ = x2;
} else {
leftX_ = x2;
rightX_ = x1;
}
}
void setRangeY(int y1, int y2) {
if (y1 <= y2) {
bottomY_ = y1;
topY_ = y2;
} else {
bottomY_ = y2;
topY_ = y1;
}
}

private:
int leftX_;
int rightX_;
int bottomY_;
int topY_;
};

經由一層介面函數的封裝
你就可以避免資料敗壞的風險


上面的例子當然不是很好
畢竟 setRangeX(x1, x2); setRangeY(y1, y2); 的介面不是很直觀
改善的設計可能是
先將座標點設計為一個叫做 Point 的 struct
再以兩個 Point 去決定座標上的一個長方形.....

但是不管怎樣 藉由上面的例子
相信你應該可以瞭解 struct 和 class 的主要適用情況了


最後
class 的成員變數全部都應該是 private
所以一定會有做為介面的成員函數存在
然而就如同上面的例子所述
將裸露的資料當作介面的 struct 一樣可以包含成員函數
那倒是沒有什麼不便之處

當然
在 c++ 中 struct 與 class 的唯一差別
只是預設為 public 或 private 的不同而已
不過上面的選擇方式
可以視為一種良好的 coding style
它給出一種暗示
讓人明白資料之間是否存在相依關係

一般而言
class 的使用情況較 struct 廣

--

直接閱讀《琴劍六記》
http://gs.cathargraph.com/p/list.html

  《琴劍六記》Facebook專頁
https://www.facebook.com/GSannals

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 219.85.214.250
※ 編輯: pnpncat 來自: 219.85.214.250 (07/23 01:27)
magic15:!!原來struct可以宣告函數!!!! 解釋很清楚 謝謝你!!! 07/23 08:33
erotic:class可以發展繼承、多型(多載、覆蓋),struct也可以? @@ 07/23 12:02
shadow0326:全都可以 還可以用struct繼承class 或class繼承struct 07/23 12:05
pnpncat:是的 除了預設為public與private的差異外 兩者功能相同 07/23 12:22
pnpncat:他們之間的差別主要是語意上而非語法上的 就像template參 07/23 12:23
pnpncat:數中使用 class 或 typename 的差別一樣 07/23 12:24
erotic:長知識了,謝謝指點,我要來學一下struct進階用法 07/23 12:34
chiuki:感謝分享!!! 02/20 23:37

你可能也想看看

搜尋相關網站