Re: [問題] 函數呼叫傳參數

看板C_and_CPP作者 (神奇的空指標)時間9年前 (2014/12/26 00:07), 編輯推噓1(1042)
留言43則, 7人參與, 最新討論串2/3 (看更多)
※ 引述《Ruid (南無地藏王菩薩)》之銘言: //原文恕刪 ---------------------------------------- 我在原文中推文有提到,這本書請把它丟了吧XD 這邊根據原POST中比較有問題的觀念作安全宣導, 這邊我也示範我的版本,若文中有謬誤還多請指教、包涵。 ---------------------------------------- 以下正文 stack *abc; ↑這個時候abc這指標不知道是指去哪(C++大多不會管你要幹嘛)。 這非常地危險,指標最好宣告跟定義時就把它new好。 而且這邊根本沒必要用到指標,應該是為了範例而範例的錯誤範例 :P abc->create(&abc); abc->insert(abc); ↑這 ... 介面設計得很糟 ... 首先呢,abc是指標變數, 傳引數&abc是這指標本身的指標,然後傳進去的參數是stack **s (原本的程式還少了形態),然後在成員函數中用*s解最外層指標, 以取得最外層指標所指的指標變數,然後把它new出來... 這樣做有意義嗎?!?!?! 千萬別這樣設計資料結構使用介面。。。 insert做得更可怕,不解釋了。 剩下是我實作的版本,不敢說有多高效、有多安全、有多正確、有多完美, 但至少比那本書正確多了。為了要簡化範例,所以使用鏈結串列(Linked list), (因為陣列版記憶體配置比較複雜),也不做安全檢查跟泛型(只做int版本)。 對了,我不知道原PO是在學指標還是學資料結構,我就當你在學資料結構吧~ 如果你是在純粹學指標,請原諒我的自High行為...反正這程式有用到指標了 = w = 編譯環境 : | 作業系統 = Windows7 64bit | IED/編譯器 = Code::Blocks 13.12 / GCC 4.8.1 | 編譯指令 = -std=c++11 (開啟C++11支援) //PS : 我這邊的push(int)跟原文的insert(i)是一樣的, //原程式create作用處於科學尚未發現之領域(?!) #include <iostream> struct Node { int value = 0; Node* pre = nullptr; }; class intStack { public: //初始化列表 intStack() : __top(nullptr), __size(0) { } //解構式 ~intStack(); void push(int); void pop(); //這邊的Const是確保size()不會被拿去賦值 unsigned int size() const { return __size; } bool empty() const { return (__size==0)?true:false; } int& top() { return __top->value; } private: Node* __top; unsigned int __size; }; intStack::~intStack() { //解構式,確保資料都有被Free掉 while( __size != 0 ) { pop(); } } void intStack::push(int n) { Node* old = __top; __top = new Node; __top->pre = old; __top->value = n; ++__size; } void intStack::pop() { Node* old = __top; __top = __top->pre; delete old; --__size; } int main() { intStack a; for(int i=0; i<10; ++i) { a.push(i); } for(int i=0; i<10; ++i) { std::cout << "top() : " << a.top() << std::endl; std::cout << "size() : " << a.size() << std::endl << std::endl; a.pop(); if( a.empty() ) { std::cout << "The stack is empty now!" << std::endl; } } return 0; } -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.252.20.53 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1419523679.A.B4F.html

12/26 00:37, , 1F
這 ID... 你今天 GO 了嗎
12/26 00:37, 1F

12/26 09:52, , 2F
名稱開頭是雙底限是reserved identifier吧...
12/26 09:52, 2F

12/26 09:52, , 3F
12/26 09:52, 3F

12/26 10:01, , 4F
然後你應該還要幫他加上一個copy ctor/assignment operator
12/26 10:01, 4F

12/26 10:01, , 5F
size() const只是讓這個method可以被const intstack使用而已
12/26 10:01, 5F

12/26 10:02, , 6F
然後(__size == 0)?true:false不就和 size() == 0 一樣嗎= =
12/26 10:02, 6F

12/26 10:52, , 7F
同上, 不要用雙底線, private member 請用單底線前飾
12/26 10:52, 7F

12/26 13:12, , 8F
C++認不得Nil 關鍵字是nullptr 沒問題的 可以當變數(?
12/26 13:12, 8F

12/26 13:38, , 9F
感謝指教,學到了,確實Private member這樣命名很糟糕
12/26 13:38, 9F

12/26 13:40, , 10F
copy建構式跟assignment運算子的話...請原諒我的偷懶XD
12/26 13:40, 10F

12/26 13:49, , 11F
其實單底線前飾也容易撞到雷,我現在看到比較多的做法
12/26 13:49, 11F

12/26 13:49, , 12F
是單底線後飾,不過我個人偏好前飾好看(?
12/26 13:49, 12F

12/26 14:02, , 13F
我覺得好看程度 _var > var_ > m_var
12/26 14:02, 13F

12/26 14:19, , 14F
size() const是為了不要發生類似 size()=5 這種狀況
12/26 14:19, 14F

12/26 14:22, , 15F
er...該怎麼說,size()傳回const本身就很奇怪 XD
12/26 14:22, 15F

12/26 14:23, , 16F
說錯 size()傳回reference本身就很奇怪 XD
12/26 14:23, 16F

12/26 14:23, , 17F
const與否反而比較旁枝末節了吧 雖然立意正確啦...
12/26 14:23, 17F

12/26 14:23, , 18F
size()不是int就是long,傳reference沒啥好處啊...
12/26 14:23, 18F

12/26 14:24, , 19F
的確size()我會宣告前後各一個const 不過原因不是這個
12/26 14:24, 19F

12/26 14:25, , 20F
const size_t size() const;
12/26 14:25, 20F

12/26 14:25, , 21F
前面加 const 很怪吧, 別人只是想用還要 const_cast
12/26 14:25, 21F

12/26 14:25, , 22F
for (size_t i = 0; i < foo.size(); i++) // orz
12/26 14:25, 22F

12/26 14:29, , 23F
return value type加const沒啥意義
12/26 14:29, 23F

12/26 14:30, , 24F
size() = 5這種東西本來就是錯的 左邊不是lvalue
12/26 14:30, 24F

12/26 14:32, , 25F
size()後面加const的意義是假設你宣告一個const intStack s;
12/26 14:32, 25F

12/26 14:32, , 26F
你可以呼叫s.size(); 如果你只有宣告unsigned size(); 那這
12/26 14:32, 26F

12/26 14:33, , 27F
個method就只能給非const的object使用
12/26 14:33, 27F

12/26 17:41, , 28F
誒對椰,我在想什麼,size的ret確不該const orz
12/26 17:41, 28F

12/26 19:46, , 29F
感謝各位的指教與參與討論┌(_ _)┐上面有兩位提到我的ID
12/26 19:46, 29F

12/26 19:49, , 30F
其實Nil是跟Lua、Ruby挖來的,ptr是純粹懶得打字XD
12/26 19:49, 30F

12/26 21:11, , 31F
this.var 最好看
12/26 21:11, 31F

12/26 22:24, , 32F
但 getter 就變 getVar() 超醜
12/26 22:24, 32F

12/26 23:36, , 33F
?! getVar() 看不懂哪裡醜,getter 不就這樣寫嗎
12/26 23:36, 33F

12/27 19:34, , 34F
這只是信仰問題吧,像是STL的Getter不會加get
12/27 19:34, 34F

12/28 22:12, , 35F
喔喔我好像看懂了
12/28 22:12, 35F

12/28 23:16, , 36F
其實getter/setter的固定格式是來自於C#(原生)跟Java的
12/28 23:16, 36F

12/28 23:16, , 37F
hibernate(Java本身沒這種慣例),所以放在C++看起來會
12/28 23:16, 37F

12/28 23:16, , 38F
滿奇怪的,因為這本來就不是C++有的東西
12/28 23:16, 38F

12/28 23:21, , 39F
最早應該是hibernate啦 可能還有更早 反正就變慣例了
12/28 23:21, 39F

01/01 01:34, , 40F
為什麼你在 Node 知道要用 member initializers 但是在
01/01 01:34, 40F

01/01 01:34, , 41F
intStack 裡面卻不使用啊...
01/01 01:34, 41F

01/07 19:14, , 42F
有喔 ... 我放在空建構式上面,不過我懶惰沒對其他
01/07 19:14, 42F

01/07 19:15, , 43F
建構式做處理,其實會有問題
01/07 19:15, 43F
文章代碼(AID): #1Kd3PVjF (C_and_CPP)
文章代碼(AID): #1Kd3PVjF (C_and_CPP)