2014-09-23 146 views
1

我碰到下面的代碼好友功能和實現

class ExDer1 : public ExBase 
{ 
public: 
    friend int Der1Fn() 
    { 
     .... 
    } 
}; 

來到我與

 friend int Der1Fn() 
     { 
      //This has an implementation .Why is it a friend then ? since it can access the private/protected variables of the ExDer1 class ? 
     } 

通常有點困惑在這裏,我希望看到類似下面的

friend int Der1Fn(); //No implementation. Indicating that the Der1Fn is a method outside this class 

這基本上意味着功能int Der1Fn()將訪問的私有變量的類ExDer1。不過這有一個實現。請有人解釋這是什麼意思嗎?

更新:

所以,如果我有以下代碼

class ExDer1 : public ExBase 
{ 
public: 
    friend int Der1Fn() 
    { 
     std::cout << "Hello World"; 
    } 
}; 

int main() 
{ 
    Der1Fn(); // error C3767: 'Der1Fn': candidate function(s) not accessible 
    //..... 
} 

我怎麼叫Der1Fn?

+0

你從哪裏知道你不能在課堂上提供朋友功能的實現? – P0W 2014-09-23 07:53:54

+0

我查看了http://msdn.microsoft.com/en-us/library/h2x4fzdz.aspx上的示例,他們沒有任何聲明爲friend的實現的示例。 – Rajeshwar 2014-09-23 07:55:01

+0

這意味着這是該功能的實施。你不明白什麼? – 2014-09-23 07:57:10

回答

2

朋友功能(或類)也可以在課外或課堂內定義。如果您在內部定義它,應該在正確的範圍內提供匹配的聲明,否則將發生依賴於參數的查找。

下面的例子是邏輯相同:

例1:

int Der1Fn(); 

class ExDer1 : public ExBase 
{ 
public: 
    friend int Der1Fn() 
    { 
     .... 
    } 
}; 

例2(推薦):

int Der1Fn() 
{ 
    .... 
} 

class ExDer1 : public ExBase 
{ 
public: 
    friend int Der1Fn(); 
}; 

我怎麼叫Der1Fn?

this相同。

+0

剛更新了我的帖子。如果它相當於我班級以外的功能,我該如何訪問它? – Rajeshwar 2014-09-23 08:12:03

+0

@Rajeshwar解釋加入 – 4pie0 2014-09-23 08:24:40

+0

您確定Der1Fn不需要在ExDer1中使用圓括號嗎? – CashCow 2014-09-23 09:02:33

2

你可以在類定義中聲明好友函數的主體(就像任何類型的函數一樣)。

但是,friend函數遵循所實現的每個函數的相同基本規則:在類定義中聲明它是一種不好的做法(內聯,重新編譯所有依賴對象的更改等)。

您引用了MSDN示例。他們只是舉例說明如何確定範圍。函數Der1Fn()位於全局名稱空間中,而不在ExDer1 :: Der1Fn()中。

爲您更新的帖子:

類Der1Fn()不具有訪問ExDer1的這個(這不是階級的一部分,它是一個外部函數,把它看作是靜態的)。

但是,在Der1Fn()的內部,您可以訪問ExDer1類型對象的私有成員變量。

+0

有時候在類體中實現它對於傾向於只需要標頭代碼的模板類非常方便.. – Pete 2014-09-23 08:05:16

+1

沒錯,但需要知道好處和缺點。如果你不使用模板或內聯,那麼在頭文件中實現大塊代碼是不明智的。 – MichaelCMS 2014-09-23 08:07:12

+0

剛剛更新了我的帖子。如果它的外部功能我如何訪問它? – Rajeshwar 2014-09-23 08:12:30

1

如果需要訪問班級的私人成員,但不應該是成員,那麼您可以將某個功能作爲朋友。朋友功能可以在班級內部或外部實施。

如果在類中聲明(並定義)了朋友函數,那麼它的範圍在周圍的名稱空間內,就好像您在那裏定義的那樣; 它只能通過參數依賴查找(ADL)找到 - 也就是說,只有在與其參數之一使用來自同一名稱空間的類型調用時才能找到它。

在這種情況下,函數沒有參數,所以根本找不到 - 這就是爲什麼你不能從main或者其他任何地方調用它。你需要在類之外以及在類中的朋友聲明中聲明該函數。

如果它有一個類類型的參數(或另一個類型在同一個命名空間中),它會更有用。然後當與參數類型稱爲它將被找到:

class ExDer1 : public ExBase 
{ 
public: 
    friend int Der1Fn(ExDer1 const &) 
    { 
     .... 
    } 
}; 

int main() 
{ 
    ExDer1 obj; 
    Der1Fn(obj); // Found by ADL 
} 

定義類中的朋友是指,被(通常)僅由ADL訪問無論如何操作符重載特別有用。