Этот вопрос был задан сегодня (Предварительная выборка двойного члена класса требует приведения к типу char *?), и принятым решением было предварительное получение возвращаемого значения функции-члена, которая возвращала переменную-член по ссылке.
Тем не менее, мне стало любопытно — если элемент меньше смещения строки кэша от начала объекта, не вызывает ли вызов функции-члена объекта неявной загрузки объекта в кэш, тем самым устраняя необходимость для проповеди члена? Разве не было бы более эффективно предварительно выбрать объект, не вызывая функцию-член (как предложено в моем ответе)?
Разве сам процесс вызова функции-члена объекта неявно загружает объект в кэш, устраняя тем самым необходимость в предварительном кэшировании элемента?
Не совсем. Например, посмотрите на этот код.
#include <iostream>
using namespace std;
class DoubleContainer {
public:
char space[8];
double double_;
double* getDoubleAddr();
};
double* DoubleContainer::getDoubleAddr()
{
return &double_;
}
int main()
{
DoubleContainer *dc = NULL;
double* dp = dc->getDoubleAddr();
cout << dp << endl;
return 0;
}
Похоже, что в строке должна быть ошибка нулевого указателя double* dp = dc->getDoubleAddr();
, При условии dc
является NULL
, Но если вы скомпилируете и запустите это, обычно нет исключений.
В коде сборки, который построен из этого, все методы объекта, такие как dc->getDoubleAddr()
, преобразуются в стандартные функции с первым параметром, являющимся адресом вызывающего объекта (в этом случае dc
). Таким образом, вызов функции не вызывает исключение нулевого указателя; аргумент просто 0x0.
Затем в коде getDoubleAddr возвращает адрес двойника внутри объекта, учитывая адрес объекта. Здесь нет необходимости обращаться к памяти — программа уже знает тип объекта и, следовательно, местоположение double_
, Он просто возвращает адрес объекта плюс его восьмибайтовое смещение от char space[8]
и программа распечатывает 0x8.