2014-11-16 29 views
19
class x 
{ 
    void xx() {} 
}; 

class y 
{ 
    friend void x::xx(); 
}; 

BuNeden ÖZEL üye işlevi başka bir sınıfın arkadaş işlevi olamaz? Ben özel bir üye işlev başka bir sınıfın bir arkadaş olmak beyan edemez Neden

error: friend function 'xx' is a private member of 'x'

gibi hatayla sonuçlanır?

+0

[C++ Arkadaş bildiriminde - kamu ve özel arasındaki farkın] olası yinelenen. (http://stackoverflow.com/questions/6407691/ arkadaş-beyan-in-c-farkı-arası-özel kamu-and-) Kesinlikle – ha9u63ar

+10

@hagubear değil kopyası. – hvd

+0

Dilin buna neden izin vermediğini mi soruyorsunuz? Bir noktada birileri bunun (kötü anlaşılır) bunun kötü bir fikir olacağını düşündü. – juanchopanza

cevap

12

[class.friend]/9:

A name nominated by a friend declaration shall be accessible in the scope of the class containing the friend declaration.

nedeni oldukça basit; Bu kuralı ihlal eder

A member of a class can be

  • private ; that is, its name can be used only by members and friends of the class in which it is declared.

özel üyeler ilgisiz sınıflar içindeki beyanlarında adlandırılacak izin vermek: private üye net ve kesin bir kural itaat eder bir uygulama ayrıntı bağlıdır açıkça izin olmadan başka bir sınıf sağlar . Bu, örneğin, özel üyenin adını, türünü veya imzasını değiştirirken veya tamamen kaldırırken sorunlu hale gelir; Bu sınıfın arayüzünü kırmaya değil.

Bu

x y arkadaşı tamamını yaparak atlatılabilir:

class x { 
    void xx() {} 
}; 

class y { 
    friend x; 
}; 

Demo.

+0

Belki de sorunu anlayamıyorum, ama tam tersi bir yol olmamalı? Senin örneğinde '' '' x' özel yöntemlere erişemezdi. –

+1

@IvanSmirnov orijinal snippet'in niyeti y' 'özel verilere erişmek için' x' bir üyesini izin vermektir. – Columbo

+0

Ah, doğru, en sezgisel şey değil. Teşekkürler, anladım. –

13

x::xxprivate yapma fikri, x::xx'un diğer sınıfların güvenmemesi gereken bir uygulama detayı olduğu varsayılır. Bu sadece x::xx'un diğer sınıflar tarafından çağrılmayacağı anlamına gelmez, yani anlamına gelir, ya da x::xx öğesinin x::xy için yeniden adlandırılması, sınıfın kendisi ve sınıfın arkadaşları dışındaki herhangi bir şeyi kırmamalıdır. x::xxx::xy için yeniden adlandırma Senin durumunda

, bu x arkadaşı olmadığı halde, bir hata var sınıfını y neden olur. x 'ın private üye erişebilir y böylece

o önleme şekli, yx arkadaş yapmaktır. Daha sonra olarak x::xx bildirebilir.

(Not: "Derleyici neden buna izin vermiyor?" Sorusuna daha doğrudan bir yanıt "Doğal olarak, buna izin vermediği için." ?. buna izin vermez" Bunu takip soruyu cevaplamak için çalışılıyor)

+0

Bir alt sınıfta özel ve geçersiz kılınmış sanal üye işlevim olabilir. Bu sanal fonksiyonun temel sınıfta yeniden adlandırılması bir şeyleri kırıyor, değil mi? ' – Columbo

+1

Hangi sorunun cevabını beğendim * tam olarak * cevap veriyorsunuz. –

+0

@Columbo Haklısınız. Bu, "anlamına gelir" ile "anlamı" arasındaki farklardan biridir. :) – hvd