[問題] member function與friend function 重複

看板C_and_CPP作者 (旅之夢)時間12年前 (2012/04/18 21:41), 編輯推噓14(14038)
留言52則, 11人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) g++ 程式碼: -----main.cpp----- #include <iostream> #include <stdlib.h> #include "Complex.h" using namespace std; int main(){ Complex a; a=Polar(5.6, 1.8); Abs(a); return 0; } -----Complex.h----- #include <iostream> #include <cmath> class Complex { public: Complex(const double re = 0, const double im = 0); Complex Polar(const double leng, const double arg); friend Complex Polar(const double leng, const double arg); double Abs(); friend double Abs(const Complex& x); private: double real; double imag; }; //Complex Polar(const double leng, const double arg); 錯誤訊息 'Polar' was not declared in this scope 如果把註解拿掉就能正確執行 但是friend Abs也沒有在class外面定義他的prototype卻能編譯過 請問版上各位高手這是為什麼呢? -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 122.123.85.57 ※ 編輯: tabinoyume 來自: 122.123.85.57 (04/18 21:42)

04/18 22:00, , 1F
真的假的,這個 int set 到底有什麼魔力
04/18 22:00, 1F
剛有打錯 更正

04/18 22:09, , 2F
函數使用前,必須先做原型宣告,C++ 標準的規定
04/18 22:09, 2F
friend那行不算是宣告嗎?

04/18 22:17, , 3F
好朋友只是朋友
04/18 22:17, 3F

04/18 22:28, , 4F
你只有說他是我的朋友 但他在哪我找不到啊...
04/18 22:28, 4F
我發覺剛剛提問的不是很恰當,我重新改過內容了 能麻煩各位在幫忙解惑嗎?

04/18 23:00, , 5F
好朋友不能給「類別本身的 method」當
04/18 23:00, 5F

04/18 23:00, , 6F
而且他的功能就只是朋友,跟原型宣告毫無關係
04/18 23:00, 6F

04/18 23:02, , 7F
我覺得這題跟friend無關,應該只是你在定義Complex.h的
04/18 23:02, 7F

04/18 23:03, , 8F
內容的時候使用到沒有forward declared的Polar
04/18 23:03, 8F

04/18 23:04, , 9F
不過只是猜測啦,畢竟你沒貼出Complex.cpp(假設叫這名)
04/18 23:04, 9F
我現在問題是Abs我也沒有事先宣告,但是卻能編譯得過 但是Polar卻不行 兩者只差在名為Abs的member function與friend function參數不一樣 而Polar是完全一樣 -----Complex.cpp----- #include "Complex.h" Complex::Complex(const double re, const double im){ real = re; imag = im; } Complex Complex::Polar(const double leng, const double arg){ real = leng*cos(arg); imag = leng*sin(arg); return *this; } double Complex::Abs(){ return sqrt(real*real+imag*imag); } Complex Polar(const double leng, const double arg){ double real = leng*cos(arg); double imag = leng*sin(arg); return Complex(real,imag); } double Abs(const Complex& x){ return sqrt(x.real*x.real+x.imag*x.imag); }

04/18 23:13, , 10F
嗯~ 原Po再確認一下這錯誤訊息的來源檔案
04/18 23:13, 10F

04/18 23:13, , 11F
可能就如樓上說的,編譯錯誤是在Complex.cpp發生的~~~
04/18 23:13, 11F
錯誤是顯示在main裡使用到Polar那行

04/18 23:30, , 12F
奇怪的是,我用 VC 照你的程式可以跑,真的可以省略...
04/18 23:30, 12F

04/18 23:31, , 13F
C++ 真是深奧難明
04/18 23:31, 13F

04/18 23:32, , 14F
妙的是我也跑得過去耶, 原po請附上編譯器和編譯參數.
04/18 23:32, 14F
g++ -ggdb -Wall -c main.cpp g++ -ggdb -Wall -c Complex.cpp g++ -ggdb -Wall -o main main.o Complex.o

04/18 23:32, , 15F
???會不會是因為friend complex()找不到他的外部function
04/18 23:32, 15F

04/18 23:33, , 16F
在這個.h裡面?
04/18 23:33, 16F

04/18 23:47, , 17F
囧",原來我剛完全把原Po的意思看反了~ 不好意思
04/18 23:47, 17F

04/18 23:47, , 18F
剛用DevC++試了一下,沒辦法仿出和原Po一樣的錯誤說~
04/18 23:47, 18F

04/18 23:48, , 19F
安安靜靜的通過說-.-"
04/18 23:48, 19F

04/18 23:50, , 20F
我用g++的確仿出了一樣的問題 @_@ 不知道標準是否有規
04/18 23:50, 20F

04/18 23:51, , 21F
定friend可不可以當成宣告
04/18 23:51, 21F

04/18 23:52, , 22F
我猜是沒有,然後一些編譯器作成有,然後導致一些未定
04/18 23:52, 22F

04/18 23:52, , 23F
義的bug @_@
04/18 23:52, 23F

04/18 23:53, , 24F
這問題真妙..
04/18 23:53, 24F

04/18 23:57, , 25F
全域函數的原型宣告,出現在 class 裡面,這不是很詭異嗎
04/18 23:57, 25F

04/18 23:59, , 26F
@p大, 是很鬼異, 不過鬼異的是 vc 竟然解析得出來.. 
04/18 23:59, 26F

04/19 00:00, , 27F
CL.exe main.cpp Complex.cpp /Fe"main.exe" 成功了..
04/19 00:00, 27F

04/19 00:01, , 28F
詭異+1,還是老老實實地在class外面寫原型宣告好了#_#"
04/19 00:01, 28F

04/19 00:02, , 29F
在裡面重宣告Complex物件存進去再return呢? (我隨便說的)
04/19 00:02, 29F
※ 編輯: tabinoyume 來自: 122.123.85.57 (04/19 00:12)

04/19 01:56, , 30F
這跟 name lookup 規則有關, Polar() 在 main() 中是
04/19 01:56, 30F

04/19 01:58, , 31F
invisible 的, 除非前面爬到定義/宣告為止, Abs() 之
04/19 01:58, 31F

04/19 01:58, , 32F
所以能叫用的原因是因為參數型別的關係, 使得找尋可匹
04/19 01:58, 32F

04/19 02:00, , 33F
配叫用的函式範圍又多了兩個選項: Complex 所在的命名
04/19 02:00, 33F

04/19 02:01, , 34F
空間以及它本身的spec
04/19 02:01, 34F

04/19 02:04, , 35F
想讓 Abs() 也一樣掛的話, 這樣呼叫即可 (Abs)(a);
04/19 02:04, 35F

04/19 02:05, , 36F
std::getline() 的使用者多多少少也遇過這種情況才是
04/19 02:05, 36F

04/19 08:12, , 37F
樓上講的並不完全正確,因為 friend 應該只有引入不可見
04/19 08:12, 37F

04/19 08:25, , 38F
的名稱... 一般的 getline 是有乖乖寫下正常定義的,但這
04/19 08:25, 38F

04/19 08:26, , 39F
裡只有寫 friend
04/19 08:26, 39F

04/19 10:00, , 40F
看似串出作業ww
04/19 10:00, 40F

04/19 10:13, , 41F
原來如此,學到一課了
04/19 10:13, 41F

04/19 10:45, , 42F
沒有「原來如此」吧... l大講的ADL這裡根本不適用啊?
04/19 10:45, 42F

04/19 10:46, , 43F
www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html
04/19 10:46, 43F

04/19 10:46, , 44F
#165 看看標準委員會的答案寫什麼...
04/19 10:46, 44F

04/19 10:49, , 45F
至於編譯器要怎麼實作就是另外的問題啦 xD
04/19 10:49, 45F

04/19 10:53, , 46F
根本問題是 friend 宣告算不算「宣告」;我只能說兩種觀點
04/19 10:53, 46F

04/19 10:56, , 47F
都有人在吵;我認為按照標準精神不管誰都找不到,gcc 目前
04/19 10:56, 47F

04/19 10:58, , 48F
讓ADL得逞就是了(因為標準好像只有列舉正常lookup必失敗
04/19 10:58, 48F

04/19 12:03, , 49F
(不好意思上面的話沒啥條理,可惜推文不能改 xD)
04/19 12:03, 49F

04/19 12:15, , 50F
樓上可以回一篇文阿XD
04/19 12:15, 50F

04/19 21:45, , 51F
唔我剛才發現 L 大才是對的,請把我上面的推文都忽略 orz
04/19 21:45, 51F

04/19 21:45, , 52F
造成大家困擾真不好意思 orz
04/19 21:45, 52F
文章代碼(AID): #1FZiIX_c (C_and_CPP)