精華區beta C_and_CPP 關於我們 聯絡資訊
所謂deflaut consructor 是指沒有宣告 constrcutor的時候,complier會自動幫我們宣告 1.empty constructor 2.copy constructor 第一個問題 我想請問 什麼叫做 沒有宣告contructor 是指 在class中 沒有宣告constructor( )的參數嗎 還是指 在class中 沒有宣告consructor 第2個問題 什麼是copy constructor 那有什麼用處的 我在網路在 看到一個範例 class CExample { public: int a,b,c; void multiply (int n, int m) { a=n; b=m; c=a*b; }; }; CExample::CExample (const CExample& rv) { a=rv.a; b=rv.b; c=rv.c; }// 這一段 似乎 就是copu constructor的寫法 不過 我在做編譯的時候 complier不給我過 他說 要在class中 宣告constructor; 不過當我宣告以後 class CExample { public: int a,b,c; CExmple(); void multiply (int n, int m) { a=n; b=m; c=a*b; }; }; complier 依然顯示相同的錯誤。 請問 是哪裡有錯??? -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 59.114.130.131
Fightsea:deflaut consructor是指具有default argument 140.122.22.174 06/22
Fightsea:的constructor 140.122.22.174 06/22
Fightsea:你連定義都弄錯了 所以會混亂 140.122.22.174 06/22
> -------------------------------------------------------------------------- < 作者: UNARYvvv (有趣生活) 看板: C_and_CPP 標題: Re: [問題] default constructor 時間: Tue Jun 21 23:06:47 2005 ※ 引述《wearebest (加油)》之銘言: : complier不給我過 : 他說 要在class中 宣告constructor; : 不過當我宣告以後 : class CExample { : public: : int a,b,c; : CExmple(); 因為以上叫做 default constructor 而且你拼錯了,上面那行函式名稱跟 class 名稱不一樣 (所以事實上拼得不一樣..也根本就不叫 constructor 哩XD) copy constructor 的宣告應該長這樣: CExample(const CExample &rhs); 一個參數,型態為本身類別 這表示你在建立一個新 CExample 物件時 能根據另一個 CExample 物件的內容來作初始化 我不確定那個參數如果不是 const reference 會不會編譯錯誤 但是照著這種標準寫法來寫準沒錯 : void multiply (int n, int m) { a=n; b=m; c=a*b; }; : }; : complier 依然顯示相同的錯誤。 : 請問 是哪裡有錯??? -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 61.59.30.19
wearebest:不好意思 我在編譯的時候 沒有拼錯 59.114.130.131 06/21
wearebest:只是 我打PO文的時候 拼錯了 59.114.130.131 06/21
> -------------------------------------------------------------------------- < 作者: aoc90058 (我是新警察Orz...) 看板: C_and_CPP 標題: Re: [問題] default constructor 時間: Tue Jun 21 23:33:06 2005 ※ 引述《wearebest (加油)》之銘言: : 所謂deflaut consructor : 是指沒有宣告 constrcutor的時候,complier會自動幫我們宣告 : 1.empty constructor 這有些像... sort( v.begin(),v.end(),greater<unsigned int> () ); 雖然說greater它並不需要引入啥東西在data做比較的動作 但他會有一個deflaut constructor 所以你還是得打出來 : 2.copy constructor class CExample { private: int a,b,c; //恕我修改到private public: CExample(const CExample& rv); void multiply (int n, int m) { a=n; b=m; c=a*b; }; }; CExample::CExample (const CExample& rv) { a=rv.a; b=rv.b; c=rv.c; } 這樣我是能夠編譯成功的 Microsoft Visual C++ Toolkit 2003 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 61.218.171.71 ※ 編輯: aoc90058 來自: 61.218.171.71 (06/21 23:35)
godfat:補充:原 po 宣告的 constructor 與定義的參數不꘠140.138.241.159 06/22
godfat:不合140.138.241.159 06/22
> -------------------------------------------------------------------------- < 作者: Fightsea (蜂蜜派) 看板: C_and_CPP 標題: Re: [問題] default constructor 時間: Wed Jun 22 06:47:32 2005 ※ 引述《wearebest (加油)》之銘言: : 所謂deflaut consructor : 是指沒有宣告 constrcutor的時候,complier會自動幫我們宣告 雖如果你去查google 第一個網頁的確是這樣定義default consructor 但是default constructor應該是指具有default argument的constructor "沒有宣告 constrcutor的時候,complier會自動幫我們宣告" 上面所寫的這個東西一般就直接叫做constructor : 我想請問 : 什麼叫做 沒有宣告contructor 沒有宣告constructor 就是指你的class裡面沒有寫關於constructor的部份 跟參數無關 constructor可以沒有參數 : 什麼是copy constructor : 那有什麼用處的 copy constructor是指當你新增一個物件的時候 想要用現有的某個物件的內容作為新物件的初始內容 則使用copy constructor 也就是假設有一個叫做House1的物件 我想要複製一棟房子的意思 House House1; 經過一些程式碼之後 House1中已經有很多member是有意義的資料 House House2( House1 ); //呼叫copy constructor 所以copy constructor的prototype如下 House( const House & ); //記得加const才符合copy的精神 然後你再自己去寫copy constructor的內容 讓House1的內容可以複製到House2中 -- 建議你先把專有名詞的意思搞懂 再去看程式碼 如果觀念懂了 程式碼有寫錯通常只是一些資料型態或是指標在出錯 這樣你應該可以自己去偵錯了... -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.122.22.174 ※ 編輯: Fightsea 來自: 140.122.22.174 (06/22 06:55) ※ 編輯: Fightsea 來自: 140.122.22.174 (06/22 06:57) > -------------------------------------------------------------------------- < 作者: myselves (...) 看板: C_and_CPP 標題: Re: [問題] default constructor 時間: Wed Jun 22 20:38:26 2005 ※ 引述《wearebest (加油)》之銘言: : 所謂deflaut consructor : 是指沒有宣告 constrcutor的時候,complier會自動幫我們宣告 應該不是這樣的~~ default constructor是指物件被定義時,沒有提供建構氏參數 像是這樣的定義: int a; 或者 MyClass myObject; 還有定義物件陣列的時候: MyClass myClassArray[100]; 顯然的這些定義都沒有提供constructor參數, 所以程式就要呼叫一個不用參數的constuctor, 這個constructor就是default constructor。 只能有一個,但是不只有一種(compiler自動產生的那個只是其中一種) Xxxxx(); 或 Xxxxx(int a = 3); 都是 (都可以不提供參數) : 1.empty constructor : 2.copy constructor 當定義一個物件並初始化為另一個物件時,例如 ClassA a; ClassA b = a; 或者傳參數進函數的時候(call by value),都會進行memberwise copy 就是把data members一個對一個做複製 第一種情況如果沒有宣告copy constructor會變成 ClassA a; ClassA b; b = a; //呼叫operator= 這種情況會需要copy constructor通常是因為有data member是指標...... 會造成兩個物件的data member(指標)指向同一塊記憶體 至於copy constructor為什麼要call by reference而不能call by value...... 因為如果call by value的話,物件被傳進去是被複製一份新的,等於還要再 呼叫一次copy constructor,會導致遞迴 (這邊我形容的很爛,可能很難看的懂= =) 而copy constructor的型態未必要跟class本身一樣 例如 Xxxxx(const Yyyyy &rhs); 是可以的(通常都是Xxxxx(const Xxxxx &rhs);) 當 Yyyyy y; Xxxxx x = y; //這時候 Xxxxx(const Yyyyy &rhs)會被呼叫 : 第一個問題 : 我想請問 : 什麼叫做 沒有宣告contructor : 是指 : 在class中 : 沒有宣告constructor( )的參數嗎 : 還是指 : 在class中 : 沒有宣告consructor : 第2個問題 : 什麼是copy constructor : 那有什麼用處的 : 我在網路在 看到一個範例 : class CExample { : public: : int a,b,c; : void multiply (int n, int m) { a=n; b=m; c=a*b; }; : }; : CExample::CExample (const CExample& rv) { : a=rv.a; b=rv.b; c=rv.c; : }// 這一段 似乎 就是copu constructor的寫法 : 不過 我在做編譯的時候 : complier不給我過 : 他說 要在class中 宣告constructor; : 不過當我宣告以後 : class CExample { : public: : int a,b,c; : CExmple(); : void multiply (int n, int m) { a=n; b=m; c=a*b; }; : }; : complier 依然顯示相同的錯誤。 : 請問 是哪裡有錯??? -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.123.225.128
UNARYvvv:推 解釋到copy ctor參數是const ref的原因~ 61.59.30.19 06/22
UNARYvvv:先前我不知道怎麼講~ 61.59.30.19 06/22
UNARYvvv:形容得一點也不爛 很好懂 61.59.30.19 06/22
myselves:那是我謙虛的XD 140.123.10.11 06/23
> -------------------------------------------------------------------------- < 作者: WanCW (笨狐狸) 看板: C_and_CPP 標題: Re: [問題] default constructor 時間: Wed Jun 22 20:58:14 2005 ※ 引述《myselves (...)》之銘言: : 而copy constructor的型態未必要跟class本身一樣 : 例如 Xxxxx(const Yyyyy &rhs); 是可以的(通常都是Xxxxx(const Xxxxx &rhs);) : 當 : Yyyyy y; : Xxxxx x = y; //這時候 Xxxxx(const Yyyyy &rhs)會被呼叫 只有型態完全相同的, 才會被視為 Copy Constructor. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.123.20.125
UNARYvvv:沒錯 61.59.30.19 06/22
khoguan:這方面要深談,是很複雜滴。220.130.208.168 06/22
myselves:沒注意到這一點^^a140.123.225.128 06/22
UNARYvvv:同意k大,只是一般的看法如TCPL/C++ Primer 61.59.30.19 06/22
UNARYvvv:是有提過 X::X(const X&) 這種形式 61.59.30.19 06/22
UNARYvvv:當然我相信絕對有更深入的探討,也許請k大哪天有 61.59.30.19 06/22
UNARYvvv:閒能夠給大家指導或是分享一下了。 謝謝~ 61.59.30.19 06/22
khoguan:C++真箇複雜,大肉腳我還在持續發現不懂的地方 ;Q220.130.208.168 06/22
> -------------------------------------------------------------------------- < 作者: khoguan (Khoguan Phuann) 看板: C_and_CPP 標題: Re: [問題] default constructor 時間: Wed Jun 22 23:23:32 2005 ※ 引述《WanCW (笨狐狸)》之銘言: : ※ 引述《myselves (...)》之銘言: : : 而copy constructor的型態未必要跟class本身一樣 : : 例如 Xxxxx(const Yyyyy &rhs); 是可以的(通常都是Xxxxx(const Xxxxx &rhs);) : : 當 : : Yyyyy y; : : Xxxxx x = y; //這時候 Xxxxx(const Yyyyy &rhs)會被呼叫 : 只有型態完全相同的, 才會被視為 Copy Constructor. Y y1; X x1 = y1; 這種寫法,在「語意」上,是以 y1 為引數,呼叫 X(const Y&) 以產生一個 X 的暫時物件,然後再以這個 X 的暫時物件做引數, 呼叫 X(const X&) 來建構 x1 這個 X 的物件。「語意」上是如此, 但在compiler實作上,C++ 標準容許其做最佳化,呼叫 X(const Y&) 時,就直接建構出 x1, 而不是執行 X(const Y&) 只產生過渡性的 暫時物件,接著再呼叫 X(const X&) 才終於建構出 x1。由於許多 編譯器都有做這種最佳化,因此很容易讓人誤以為只需要有 X(const Y&) 就能寫 X x1 = y1; Anyway,編譯器仍然得要求程式符合需要兩層建構子的「語意」限制, 也就是說,即使是做這種最佳化的編譯器,仍然得先檢查 X(const X&) 這個建構子是不是能夠被存取以執行,否則,就不能通過編譯。例如: class Y {}; class X { public: X() { cout << "X()\n"; } X(const Y&) { cout << "X(const Y&)\n"; } X(const X&) { cout << "X(const X&)\n"; } }; int main() { Y y1; X x1 = y1; } 上述可以通過編譯,並正確執行( <iostream>等等請自己加:)。但是 若動個手腳,將 X(const X&)移到 private: 區,那就不行通過編譯啦。 class Y {}; class X { public: X() { cout << "X()\n"; } X(const Y&) { cout << "X(const Y&)\n"; } private: X(const X&) { cout << "X(const X&)\n"; } }; int main() { Y y1; X x1 = y1; } Comeau compiler 的錯誤訊息說得很清楚: error: "X::X(const X &)" is inaccessible (Even though the copy was eliminated, the standard still requires it to be accessible) X x1 = y1; ^ 這樣就可看出 X(const X&) 對於 X x1 = y1; 這個敘述的必要性了。 當然,若根本不宣告 X(const X&) 的話,compiler 依標準會默默地 (implicitly)幫我們生出一個來,那當然還是可以編譯執行的。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.130.208.168
elsvent:要注意的是有用到pointer就要小心了 61.62.218.129 06/22
※ 編輯: khoguan 來自: 220.130.208.168 (06/23 11:53) > -------------------------------------------------------------------------- < 作者: UNARYvvv (有趣生活) 看板: C_and_CPP 標題: Re: [問題] default constructor 時間: Wed Jun 22 23:58:39 2005 ※ 引述《khoguan (Khoguan Phuann)》之銘言: : ※ 引述《WanCW (笨狐狸)》之銘言: : : 只有型態完全相同的, 才會被視為 Copy Constructor. : Y y1; : X x1 = y1; : 這種寫法,在「語意」上,是以 y1 為引數,呼叫 X(const Y&) : 以產生一個 X 的暫時物件,然後再以這個 X 的暫時物件做引數, : 呼叫 X(const X&) 來建構 x1 這個 X 的物件。「語意」上是如此, : 而 compiler 實作上,C++ 標準容許其做最佳化,直接呼叫 X(const Y&) : 來建構 x1, 而不用第一步執行 X(const Y&) 以產生過渡性的暫時 : 物件。 想請問一下最後三行 是直接呼叫 X(const Y&) 沒錯,畢竟傳入引數就是一個 Y 但那句「而不用第一步執行 X(const Y&) .....(略)」 有點看不太懂了 為其他型別定義不同 constructor 還蠻有用的 有時候還會定義一組提供互轉的行為 例如若有某個 Integer class 那它能夠以一個 int 初始化也蠻合理的 要能讓 Integer class 被轉成 int 應該也是可以提供的功能 class X{ int _val; public: X(int i=0) : _val(i) {} operator int() const { return _val; } }; void show(int i){ cout<<i<<endl; } int main(){ X x1 = 123; show(x1); return 0; } 然後有時候反而要刻意要避免編譯器自動進行轉換 又得在 constructor 前加上 explicit ... 的確 C++ 太多東西了 不過很多東西還真的蠻有趣的~ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 61.59.30.19 ※ 編輯: UNARYvvv 來自: 61.59.30.19 (06/23 00:17)
khoguan:原先看不懂的地方我已回頭做了修飾,謝謝!220.130.208.168 06/23
UNARYvvv:well..我也看懂了 謝謝 61.59.30.19 06/23
> -------------------------------------------------------------------------- < 作者: cplusplus (永夜) 看板: C_and_CPP 標題: Re: [問題] default constructor 時間: Thu Jun 23 00:13:27 2005 ※ 引述《UNARYvvv (有趣生活)》之銘言: : ※ 引述《khoguan (Khoguan Phuann)》之銘言: : : Y y1; : : X x1 = y1; : : 這種寫法,在「語意」上,是以 y1 為引數,呼叫 X(const Y&) : : 以產生一個 X 的暫時物件,然後再以這個 X 的暫時物件做引數, : : 呼叫 X(const X&) 來建構 x1 這個 X 的物件。「語意」上是如此, : : 而 compiler 實作上,C++ 標準容許其做最佳化,直接呼叫 X(const Y&) : : 來建構 x1, 而不用第一步執行 X(const Y&) 以產生過渡性的暫時 : : 物件。 : 想請問一下最後三行 : 是直接呼叫 X(const Y&) 沒錯,畢竟傳入引數就是一個 Y : 但那句「而不用第一步執行 X(const Y&) .....(略)」 : 有點看不太懂了 X x=y; => X x=X(y); 語意上本來該是這樣 C++ ISO定義為直接... X x(y); 這樣 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.115.205.46 > -------------------------------------------------------------------------- < 作者: UNARYvvv (有趣生活) 看板: C_and_CPP 標題: Re: [問題] default constructor 時間: Thu Jun 23 00:29:18 2005 ※ 引述《cplusplus (永夜)》之銘言: : ※ 引述《UNARYvvv (有趣生活)》之銘言: : : 想請問一下最後三行 : : 是直接呼叫 X(const Y&) 沒錯,畢竟傳入引數就是一個 Y : : 但那句「而不用第一步執行 X(const Y&) .....(略)」 : : 有點看不太懂了 : X x=y; => X x=X(y); 語意上本來該是這樣 : C++ ISO定義為直接... : X x(y); 這樣 嗯 我懂你的意思 謝了~ 關於這個我一向是把 X x(y); X x=X(y); X x=y; 三者當作等義 ( 記得以前看 C++ Primer 作者還特別釐清 X x=y; 到底是執行 operator= 還是 copy constructor ) 不過 X x=y; 也只限單一參數的 constructor 能這樣用了 個人平時為了統一 constructor 的寫法,倒是只會寫 X x(y); 的初始形式.. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 61.59.30.19 ※ 編輯: UNARYvvv 來自: 61.59.30.19 (06/23 00:51)
UNARYvvv:經過 khoguan 板友提醒,explicit時寫法就有差別 61.59.30.19 06/23
khoguan:習慣寫 X x(y); 不錯,無論有無explicit都能用 :)220.130.208.168 06/23
> -------------------------------------------------------------------------- < 作者: khoguan (Khoguan Phuann) 看板: C_and_CPP 標題: Re: [問題] default constructor 時間: Thu Jun 23 00:48:57 2005 ※ 引述《cplusplus (永夜)》之銘言: : ※ 引述《UNARYvvv (有趣生活)》之銘言: : : 想請問一下最後三行 : : 是直接呼叫 X(const Y&) 沒錯,畢竟傳入引數就是一個 Y : : 但那句「而不用第一步執行 X(const Y&) .....(略)」 : : 有點看不太懂了 : X x=y; => X x=X(y); 語意上本來該是這樣 可以這樣理解,但是若真的寫成 X x = X(y); 就是明示地(explicitly) 用 y 建構出一個 X 的暫時物件,和 X x = y; 那個 y 用隱含的(implicit) 方式建構出一個 X 的暫時物件不完全一樣。 : C++ ISO定義為直接... : X x(y); 這樣 X x=y; 和 X x(y); 兩者是不同的。 前者的語意要兩層的 ctor, 後者只是一層 ctor. 前者遇到 explict X(const Y&); 就編譯不過,後者可以。 這個 explict 就是上述 explicit 和 implicit 不完全一 樣的地方。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.130.208.168
cplusplus:這些我清楚啦 :p 感謝補充說明 140.115.205.46 06/23
UNARYvvv:嗯..這算進一步的探討了..先前我也沒歸入此情況 61.59.30.19 06/23
khoguan:不好意思,我班門弄斧了 ^^220.130.208.168 06/23
UNARYvvv:k兄考慮周到 別這麼說啦 很多地方還靠您解惑哩~ 61.70.137.117 06/23