Inline и друзья

Inline

В некоторых случаях можно дать совет компилятору встроить реализацию функции в местах вызова данной функции. Таким образом функция не будет вызвана, а ее тело будет скопировано и встравлено в место вызова, ресурсы, которые могли бы быть потрачены на вызов этой функции, — сохраняются! Минусом является лишь увеличение компилируемого кода за счет того, что встроенная функция раскрывается в коде при каждом вызове (особенно если она длинная и/или её вызывают много раз). В некоторых случаях это позволяет ускорить программу. Рассмотрим пример:

#include <iostream>
using namespace std;

int max(int a, int b)
{
    return a < b ? b : a;
}
 
int main()
{
    cout << max(7, 8) << endl;
    cout << max(5, 4) << endl;
    return 0;
}

Эта программа дважды вызывает функцию max(), т.е. дважды расходуются ресурсы на вызов функции. Поскольку max() является довольно таки короткой функцией, то это идеальный вариант для её конвертации во встроенную функцию:

inline int max(int a, int b)
{
    return a < b ? b : a;
}

Теперь, вероятно при компиляции функции main(), код будет выполнен следующим образом:

int main()
{
    cout << (7 < 8 ? 8 : 7) << endl;
    cout << (5 < 4 ? 4 : 5) << endl;
    return 0;
}

Все методы, определенные внутри класса, являются inline

Если вы используете современный компилятор, то нет необходимости использовать ключевое слово inline.

Дружественные классы

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

struct A {
	friend struct B;
 private:
	int _x;
	int _y;
};
 struct B {
	void increase(A const& a, int d) { a._x += d; a._y += d; }
};

Дружественные функции

Дружественная функция — это функция, которая имеет доступ к закрытым членам класса, как если бы она сама была членом этого класса. Во всех других отношениях дружественная функция является обычной функцией. Ею может быть, как обычная функция, так и метод другого класса. Для объявления дружественной функции используется ключевое слово friend перед прототипом функции, которую вы хотите сделать дружественной классу. Неважно, объявляете ли вы её в public- или в private-зоне класса. Например:

class Anything
{
private:
    int _value = 0
public:
    void add(int value) { _value += value; }
 
    // Делаем функцию reset() дружественной классу Anything
    friend void reset(Anything &anything);
};
 
// Функция reset() теперь является другом класса Anything
void reset(Anything &anything)
{
    // И мы имеем доступ к закрытым членам объектов класса Anything
    anything._value = 0;
}
 
int main()
{
    Anything one;
    one.add(4); // добавляем 4 к _value
    reset(one); // сбрасываем _value в 0
 
    return 0;
}

Стоит избегать friend, так как данный подход нарушает инкапсуляцию