2014-09-23 7 views
1

я наткнулся на следующий кодFriend функция и реализация

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. Однако это имеет реализацию. Может ли кто-нибудь объяснить, что это значит?

Update:

Так что, если у меня есть следующий код

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

+0

Я посмотрел пример на http://msdn.microsoft.com/en-us/library/h2x4fzdz.aspx, у них не было примера с реализацией, объявившей друга. – Rajeshwar

+0

Это означает, что это реализация функции. Что ты не понимаешь? –

ответ

2

Функция друга (или класс) может быть определена вне или внутри класса. Если вы определите его внутри, вы должны предоставить соответствующее объявление в правильной области, или произойдет поиск зависимых от аргументов.

Следующие примеры являются логически же:

Пример 1:

int Der1Fn(); 

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

Пример 2 (рекомендуется):

int Der1Fn() 
{ 
    .... 
} 

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

Как позвонить Der1Fn?

As simle as this.

+0

только что обновил мое сообщение. Если это эквивалентно функции вне моего класса, как мне получить к ней доступ? – Rajeshwar

+0

@Rajeshwar добавлено – 4pie0

+0

Вы уверены, что Der1Fn не нуждается в круглых скобках в ExDer1? – CashCow

2

Вы можете объявить тело функции друга внутри определения класса (например, для любого типа функции).

Однако функция friend выполняет те же основные правила для каждой функции, когда-либо реализованной: неправильная практика объявлять ее в определении класса (встраивание, перекомпиляция всех зависимых объектов при изменении и т. Д.).

Вы ссылаетесь на пример MSDN. Они просто сделали пример, чтобы показать, как это делается. Функция Der1Fn() находится в глобальном пространстве имен, а не в ExDer1 :: Der1Fn().

Для обновленного поста:

Класса Der1Fn() не имеет доступа к ExDer1-х это (это не часть класса, это внешняя функция, думать об этом как статических).

Однако внутри тела Der1Fn() вы можете получить доступ к частным переменным-членам объектов типа ExDer1.

+0

Иногда реализация его в классе класса очень удобна для классов шаблонов, которые, как правило, имеют код заголовка. – Pete

+1

Правда, но нужно знать как преимущества, так и недостатки. Если вы не используете шаблоны или встроенные строки, неразумно внедрять большие куски кода внутри заголовка. – MichaelCMS

+0

Только что обновил мое сообщение. Если это внешняя функция, как я могу ее получить? – Rajeshwar

1

Вы должны сделать функцию другом, если ей необходимо получить доступ к закрытым членам класса, но не должно быть членом. Функция friend может быть реализована либо внутри, либо вне класса.

Если функция друга объявлена ​​(и определена) только внутри класса, то она находится в пределах области пространства имен, как если бы вы определили ее там; , но он может быть найден только зависимым от аргумента поиска (ADL) - то есть его можно найти только в том случае, если он вызван с типом из того же пространства имен, что и один из его аргументов.

В этом случае функция не имеет аргументов, поэтому ее невозможно найти вообще - вот почему вы не можете ее вызывать от main, или даже из другого места. Вам нужно объявить функцию вне класса, а также в объявлении друга внутри класса.

Было бы более полезно, если бы у него был аргумент типа класса (или другого типа, охваченного в том же пространстве имен); то он будет найден при вызове с этим типом аргумента:

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

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

Определением друга внутри класса особенно полезно для операторов перегрузок, которые (как правило) только доступ к которым ADL в любом случае.

Смежные вопросы