2010-12-06 2 views
7

Что происходит, когда вы делаете членскую функцию класса своим другом !?Создание функции-члена друга

Приведенный ниже код компилируется и запускается. Без объявления друга создается «слишком много аргументов для оператора» (и это правильно). Я понимаю, что делать это не имеет никакого смысла, но может ли кто-нибудь сказать мне, что здесь происходит? Помогает ли друг компилятору каким-то образом опустить параметр по умолчанию?

class Test 
{ 
public: 
    friend bool operator<(Test& lhs, Test& rhs) 
    { 
    return true; 
    } 
}; 

int main(int c, char** argv) 
{ 
    Test test1; 
    Test test2; 

    return test1 < test2; 
} 
+1

Чтобы ответить на ваш вопрос: Друзья не могут быть членами класса дружбы в C++ 03, но это разрешено в C++ 0x. – 2010-12-06 05:07:44

ответ

9

Разница заключается в том, что друг не является членом, даже если все определение появляется в классе; скорее, функция помещается в окружающее пространство имен. Таким образом, нет указателя . Хотя член operator< работает неявно с this и явным правым аргументом, friend нуждается как в аргументе слева, так и в правой части, явно предоставляемом как параметры функции - следовательно, дополнительный параметр. Ваша версия friend эквивалентна включению функции после класса, за исключением того, что она имеет доступ к элементам и базам и неявно inline (хотя это не означает, что компилятор должен встроить его - это всего лишь подсказка, но это важно в отношении правила одного определения, поскольку ваша функция friend может быть включена из многих единиц перевода и ссылки без проблем).

1

Что происходит, когда вы делаете функцию-члена класса друг себе !?

Это не имеет никакого смысла. Как может функционировать член класса друг этого же класса?

Вы перегрузили operator < в качестве функции друга (не как функция-член). Предоставление определения (тела) функции друга внутри класса является законным. Однако это незаконно использовать this внутри его определения

friend bool operator<(Test& lhs, Test& rhs) 
{ 
    *this ; //error 
    return true; 
}