ref B f()
- это функция, которая возвращает B по ссылке. B является ссылкой на класс. Поэтому он возвращает ссылку на класс по ссылке. Это не глупость в D, потому что ссылки на классы могут быть восстановлены:
auto a = new A;
a.f() = new B; // rebinds a.b, possible due to return by ref
Аналогично, вы также можете иметь указатели на ссылки на классы в D:
class A
{
B b;
/* ... */
B* f()
{
return &b;
}
}
auto a = new A;
B* b = a.f(); // pointer to reference to instance of class B
*b = new B; // updates a.b
Для pure
функций-членов неявный ссылочный параметр this
- это просто еще один параметр. Это считается частью ввода. При том же объекте this
и тех же обычных параметрах выходные данные всегда остаются одинаковыми.
С помощью функции-члена const
вы не знаете, является ли объект this
изменчивым или неизменным. Это может быть либо - функция-член const
обещает не изменять его в любом случае. При использовании функции-члена immutable
объект this
всегда неизменен. Таким образом, ссылка this
может передаваться как неизменяемый аргумент другой функции или назначаться неизменяемым переменным.
При принятии решения о том, когда следует заботиться о const
, immutable
, pure
и nothrow
, вы должны учитывать, действительно ли вам нужны эти различные гарантии в коде клиента. Если вы пишете библиотеку для общего пользования, вы, вероятно, этого не знаете, поэтому в этих случаях лучше предоставить как можно больше гарантий.
Ситуация, возможно, иная для final
. Используйте его, если вы не хотите, чтобы клиентский код случайно переопределял функцию, которая не имеет смысла переопределять или не предназначена для переопределения, или когда вы хотите дать компилятору больше возможностей для оптимизации вызовов этой функции. Финальные функции, которые не переопределяют какие-либо функции (с override
) и не реализуют никаких интерфейсных функций, не обязательно должны быть виртуальными функциями, что снижает накладные расходы на вызов.