//
};
Foo &Foo::operator=(const Foo &rhs) & {
//
return *this;
}
Квалификаторы ссылки & или && означают, что указатель this может указывать на r- или l-значение соответственно. Подобно спецификатору const, квалификатор ссылки может быть применен только к (нестатической) функции-члену и должен присутствовать как в объявлении, так и в определении функции.
Функцию, квалифицированную символом &, можно применить только к l-значению, а функцию, квалифицированную символом &&,— только к r-значению:
Foo &retFoo(); //
//
Foo retVal(); //
Foo i, j; //
i = j; //
retFoo() = j; //
retVal() = j; //
i = retVal(); //
//
Функция может быть квалифицирована и ссылкой, и константой. В таких случаях квалификатор ссылки должен следовать за спецификатором const:
class Foo {
public:
Foo someMem() & const; //
//
Foo anotherMem() const &; //
};
Подобно тому, как можно перегрузить функцию-член на основании константности параметра (см. раздел 7.3.2), ее можно перегрузить на основании квалификатора ссылки. Кроме того, функцию можно перегрузить на основании квалификатора ссылки и константности. В качестве примера придадим классу Foo член типа vector и функцию sorted(), возвращающую копию объекта класса Foo, в котором сортируется вектор:
class Foo {
public:
Foo sorted() &&; //
Foo sorted() const &; //
//
private:
vector
};
//
Foo Foo::sorted() && {
sort(data.begin(), data.end());
return *this;
}
//
//
Foo Foo::sorted() const & {
Foo ret(*this); //
sort(ret.data.begin(), ret.data.end()); //
return ret; //
}
При выполнении функции sorted() для r-значения вполне безопасно сортировать вектор-член data непосредственно. Объект является r-значением, а это означает, что у него нет никаких других пользователей, поэтому данный объект можно изменить непосредственно. При выполнении функции sorted() для константного r- или l-значения изменить этот объект нельзя, поэтому перед сортировкой вектор-член data необходимо скопировать.
Поиск перегруженной функции использует свойство l-значение/r-значение объекта, вызвавшего функцию sorted() для определения используемой версии:
retVal().sorted(); //
retFoo().sorted(); //
//
При определении константных функций-членов можно определить две версии, отличающиеся только тем, что одна имеет квалификатор const, а другая нет. Для ссылочной квалификации функций ничего подобного по умолчанию нет. При определении двух или более функций-членов с тем же именем и тем же списком параметров следует предоставить квалификатор ссылки для всех или ни для одной из этих функций:
class Foo {
public:
Foo sorted() &&;