Re: [問題] 傳遞多個引數是否會自動建構成類別物件

看板C_and_CPP作者 (爵士鼓王)時間10年前 (2013/08/10 00:03), 編輯推噓21(22175)
留言98則, 18人參與, 最新討論串2/2 (看更多)
※ 引述《siaco (@@)》之銘言: : ※ 引述《QQ29 (我愛阿蓉)》之銘言: : : 今天無意間發現我不太能解釋這個現象 : : class Bar : : { : : public: : : Bar(int a) : : { : : } : : ~Bar() : : { : : } : : }; : : void Foo(Bar &a) : : { : : } : : int main() : : { : : Foo(56); : : } : : 這不會過 但我不太會解釋 是為什麼 : : 是因為R value嗎? : : 但是我加上const後 : : 就可以build過了~~ : : void Foo(const Bar &a) : : 我更想不懂 為什麼有差別了 : : 請各位指點迷津謝謝~ : 小弟看了這題目後有幾個問題, : Foo(56)是用const temp變數存 56 ? : 然後再一個temp Bar物件利用上面的const temp變數去建構? : 以上的推論是對的嗎? : 若推論正確,那建構子的變數有多個時, : 如 Bar的建構子為Bar(int A,char b) : 若傳入Foo(56,'b')也會自動建構Bar嗎? : 另外,若Bar的建構子有多個的情況, : 會自動搜尋對應的建構子嗎? 編譯器之所以會強制使用 const 是因為不允許你修改暫存物件,因為修改暫存物件沒有 意義!在 DOS 時代的 Turbo C++ 或是 Borland C++ 或許可以用非 const 方式參考暫 存變數. 當你用整數型態呼叫 Foo(Bar &) 函式編譯器會選擇 Bar(int) 建構子的版本, 這時候編譯器會產生 Bar 的暫存物件,如果要用多參數的方式引導編譯器做 型態轉換的話, 或許要改成這樣: class Bar { public: Bar(int a){} // 支援 2 個參數的版本 Bar(int A, char b){} ~Bar(){} }; void Foo(int A, char b) { // 以 2 個參數建構 bar 物件 Bar bar(56, 'b'); } void main(void) { Foo(56, 'b'); } -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.141.146.62

08/10 00:07, , 1F
gnu gcc 用 void main 不太正確喔
08/10 00:07, 1F

08/10 00:53, , 2F
標題被修改過了沒辦法串原本post...
08/10 00:53, 2F

08/10 00:54, , 3F
不過用[]還是可以,ptt真聰明
08/10 00:54, 3F

08/10 00:59, , 4F
void main(void) 的寫法是可行的唷^^
08/10 00:59, 4F

08/10 02:10, , 5F
void main(void) 是不行的唷^^
08/10 02:10, 5F

08/10 02:16, , 6F
雖然這個寫法較傳統,但是語法與文法都正確哦^^
08/10 02:16, 6F

08/10 04:17, , 7F
莫非樓上是Embeded System的GCC XD
08/10 04:17, 7F

08/10 19:57, , 8F
void main(void) 語法正確? 我記錯標準了嗎? Q_Q
08/10 19:57, 8F

08/10 20:04, , 9F
語法是正確 但是C++忘記哪個版本開始規定main return
08/10 20:04, 9F

08/10 20:04, , 10F
type一定要是int
08/10 20:04, 10F

08/10 20:12, , 11F
我找了 C89 跟 C++98 標準都是規定要 int
08/10 20:12, 11F

08/10 20:12, , 12F
是我會錯意還是更早的標準?
08/10 20:12, 12F

08/10 20:14, , 13F
大部份範例程式都是使用 int main(void) 然後回傳一個 0 給
08/10 20:14, 13F

08/10 20:17, , 14F
作業系統,但如果這真的是標準,那編譯器顯然會出現錯誤了.
08/10 20:17, 14F

08/10 20:18, , 15F
目前我使用的 Visual C++ 都接受 void main(void) 與
08/10 20:18, 15F

08/10 20:19, , 16F
語法符不符合標準跟編譯器怎麼實作有必然性嗎?
08/10 20:19, 16F

08/10 20:19, , 17F
int main(void),各位可以把 C++ 專案改成原生 C++ 類型來
08/10 20:19, 17F

08/10 20:20, , 18F
OK. 我猜如果是 Freestanding environment 應該是沒錯的?
08/10 20:20, 18F

08/10 20:21, , 19F
用 void main(void) 來寫發現也可通過編譯.
08/10 20:21, 19F

08/10 20:23, , 20F
不巧我的 Apple clang v4 不會過. 蘋果不意外 (?)
08/10 20:23, 20F

08/10 20:25, , 21F
呵呵~我沒用過 Apple 的,我使用的 Turbo C++ 與
08/10 20:25, 21F

08/10 20:25, , 22F
Borland C++, Windows 的 Visual C++ 任何版本的原生 C++
08/10 20:25, 22F

08/10 20:27, , 23F
不巧我的 g++ 也不行. 真奇怪.
08/10 20:27, 23F

08/10 20:27, , 24F
專案都可用 void main(void) 方式,C++ .Net 專案似乎也是跟
08/10 20:27, 24F

08/10 20:29, , 25F
著標準走.
08/10 20:29, 25F

08/10 20:37, , 26F
嗯. g++ 怎麼不照標準來呢. (疑惑)
08/10 20:37, 26F

08/10 20:42, , 27F

08/10 20:46, , 28F
其實這是完全看個人編碼風格,但如果編譯器不接受 void 的
08/10 20:46, 28F

08/10 20:48, , 29F
方式那就需改用 int 了,g++ 的標準是對的,因為它符合文件規
08/10 20:48, 29F

08/10 20:49, , 30F
範,Visual C++ 的方式也不能說是錯的,只是它保留了傳統與彈
08/10 20:49, 30F

08/10 20:50, , 31F
性,至於怎麼使用就看個人怎麼選擇了^^
08/10 20:50, 31F

08/10 20:52, , 32F
所以 void main(void) 語法是正確的嗎?
08/10 20:52, 32F

08/10 20:55, , 33F
語法是對的,但是否符合規範完全取決於編譯器了.
08/10 20:55, 33F

08/10 21:05, , 34F
那有什麼語法是不對的?
08/10 21:05, 34F

08/10 21:11, , 35F
所以簡單講 VC 不符合規範地開了 void main 這個後門就是了
08/10 21:11, 35F

08/10 22:36, , 36F
void main(void) 與 int main(void) 都是屬於 C 與 C++ 的
08/10 22:36, 36F

08/10 22:39, , 37F
主程式,這個在 16 bit 時代是可用的,就好像是 Windows API
08/10 22:39, 37F

08/10 22:41, , 38F
有支援 16 bit 與 32 bit,那為什麼 Windows 還持續保留了
08/10 22:41, 38F

08/10 22:44, , 39F
16 bit 的版本,要使用那一個版本見人見智了^^
08/10 22:44, 39F

08/10 22:56, , 40F
更簡單的說是「不符合規範不代表不可以用」.
08/10 22:56, 40F

08/10 23:04, , 41F
你講的是"可用性" 我好奇的是 "正確性". void Main()也可以用
08/10 23:04, 41F

08/10 23:04, , 42F
我以前寫的 Compiler 還可以用 int Q_Q() 當 main
08/10 23:04, 42F

08/10 23:17, , 43F
這個就是屬於相容性的議題了,因為必竟 C++ 程式在經過編譯
08/10 23:17, 43F

08/10 23:18, , 44F
後會產生組合語言程式,然後再透過組譯與連結產生出機器碼,
08/10 23:18, 44F

08/10 23:20, , 45F
只要能產生出 x86 指令碼為何不用?
08/10 23:20, 45F

08/10 23:22, , 46F
哈哈 對不起 我可能表達能力有問題. >_<
08/10 23:22, 46F

08/10 23:29, , 47F
哈~好像違背原始議題了...^^
08/10 23:29, 47F

08/10 23:33, , 48F
是阿. 浪費時間
08/10 23:33, 48F

08/10 23:35, , 49F
早點知道 int Q_Q() 是正確的語法就好了.
08/10 23:35, 49F

08/10 23:51, , 50F
被推文數騙進來結果只看到跳針...
08/10 23:51, 50F

08/10 23:52, , 51F
我只覺得 ID 叫 GNUGCC 應該要更尊重 GCC 一點吧
08/10 23:52, 51F

08/10 23:53, , 52F
不過這應該也可以成為簽名檔的好題材
08/10 23:53, 52F

08/11 00:43, , 53F
Feis : int Q_Q() 這個語法正確但是欠缺可讀性.
08/11 00:43, 53F

08/11 00:46, , 54F
uranusjr : 並非不尊重 GCC,純屬個人編碼風格,況且這個寫法
08/11 00:46, 54F

08/11 00:47, , 55F
對於一些從 16 bit 時代開始就在寫程式的人就知道代表的意
08/11 00:47, 55F

08/11 00:49, , 56F
義.
08/11 00:49, 56F

08/11 01:15, , 57F
代表的意義就是「我還活在16bit時代」
08/11 01:15, 57F

08/11 01:16, , 58F
「雖然有些compiler不能編我的code,但這是我的風格」
08/11 01:16, 58F

08/11 01:17, , 59F
有些東西能跑只是為了向下相容舊code
08/11 01:17, 59F

08/11 01:18, , 60F
不代表他是值得推薦的做法
08/11 01:18, 60F

08/11 01:21, , 61F
堅持 iostream.h 拒用 namespace 大概也是一種風格
08/11 01:21, 61F

08/11 01:23, , 62F
K&R的函數宣告方式也算是另一種風格
08/11 01:23, 62F

08/11 06:57, , 63F
沒錯,只是相容性的問題,如果編譯器不支援舊式寫法就必需改
08/11 06:57, 63F

08/11 06:59, , 64F
成新式了,重點是舊式跟新式的寫法都必需了解然後從中擇一.
08/11 06:59, 64F

08/11 08:09, , 65F
取這樣的 ID 講這種話... 是在搞笑嗎 XD
08/11 08:09, 65F

08/11 08:16, , 66F
這選都不用選,回傳值型別為 int 本來就是語言標準
08/11 08:16, 66F

08/11 08:17, , 67F
完全看不出 void 哪裡有彈性...
08/11 08:17, 67F

08/11 14:51, , 68F
看到拿vc 6出來講 都笑到肚子痛了
08/11 14:51, 68F

08/11 15:51, , 69F
我也從 16 bits 開始寫,但我不知道這有什麼意義 XD
08/11 15:51, 69F

08/11 15:51, , 70F
這一定是我學藝不精 >"<
08/11 15:51, 70F

08/11 17:57, , 71F
爭議是來自於設計跟實作之間的不完全一致。
08/11 17:57, 71F

08/11 17:58, , 72F
自然衍生出"實作中有但設計中沒有的用法"該不該去用。
08/11 17:58, 72F

08/11 19:21, , 73F
實作中有規範中沒有 -> strcpy_s
08/11 19:21, 73F

08/11 20:21, , 74F
Visual C++ 有支援舊式的寫法並且編譯不會有任何錯誤跟警告
08/11 20:21, 74F

08/11 20:22, , 75F
有它的功能所在,它可以相容於舊式寫法而不必重新修改,
08/11 20:22, 75F

08/11 20:23, , 76F
這個就是 Visual C++ 的彈性.
08/11 20:23, 76F

08/11 20:24, , 77F
我剛把 void main(void) 與 int main(void) 轉換成組合語言
08/11 20:24, 77F

08/11 20:24, , 78F
的結果就是,這 2 種寫法導致組合語言碼相同,也就是這樣:
08/11 20:24, 78F

08/11 20:25, , 79F
xor ax,ax
08/11 20:25, 79F

08/11 20:25, , 80F
ret
08/11 20:25, 80F

08/11 20:26, , 81F
顯示作業系統會從 ax 取得為 0 的數值.
08/11 20:26, 81F

08/11 20:27, , 82F
所謂的編碼風格不代表一定要這樣做,只是個人寫碼習慣不同,
08/11 20:27, 82F

08/11 20:28, , 83F
要怎麼使用完全取決於屬於自已的習慣.
08/11 20:28, 83F

08/11 20:43, , 84F
那是顯示你寫void main, VC仍然幫你改成int main
08/11 20:43, 84F

08/11 20:45, , 85F
取這種id講這種話實在是...
08/11 20:45, 85F

08/11 20:49, , 86F
呵呵~ Visual C++ 好像不會修改客戶端的程式碼唷^^
08/11 20:49, 86F

08/11 20:51, , 87F
各人編碼風格與 ID 無關...請各位不要做過多的連想^^
08/11 20:51, 87F

08/12 17:41, , 88F
感覺覺像是看見#include <stdio.h>和#include <stdio>
08/12 17:41, 88F

08/12 17:42, , 89F
的戰爭 = =
08/12 17:42, 89F

08/12 17:45, , 90F
不過int main(void)才是對的呦,VC是幫你做掉這部份了
08/12 17:45, 90F

08/12 20:06, , 91F
我用 Visual C++ 2008 以 Debug 啟動反組譯看到原始碼沒變
08/12 20:06, 91F

08/12 20:07, , 92F
唷^^但組合語言卻是相同的.
08/12 20:07, 92F

08/12 20:08, , 93F
Visual C++ 6.0 更簡潔,只有這段組合語言程式 :
08/12 20:08, 93F

08/12 20:08, , 94F
ret 2
08/12 20:08, 94F

08/12 20:10, , 95F
顯然 Visual C++ 2008 會再次確認 eax 暫存器為 0,只是少用
08/12 20:10, 95F

08/12 20:11, , 96F
了 2 個位元組的堆疊空間,各位可以試看看.
08/12 20:11, 96F

08/12 20:16, , 97F
到底為什麼gnugcc要一直用visual c++ orz
08/12 20:16, 97F

08/12 20:22, , 98F
ID應該取MSVCPP
08/12 20:22, 98F
文章代碼(AID): #1I1HBMAR (C_and_CPP)
文章代碼(AID): #1I1HBMAR (C_and_CPP)