Приведенный ниже код взят из LevelDB. Я даю два блока кода для лучшего понимания. Я не могу понять, что происходит.
ThreadState — это структура, и я написал здесь, чтобы облегчить ее чтение.
struct ThreadState {
int tid; // 0..n-1 when running in n threads
Random rand; // Has different seeds for different threads
Stats stats;
SharedState* shared;
ThreadState(int index)
: tid(index),
rand(1000 + index) {
}
};
Является ли помеченный код ниже экземпляром объекта класса Benchmark? Что происходит в отмеченном коде ниже?
void Run() {
PrintHeader();
Open();
const char* benchmarks = FLAGS_benchmarks;
while (benchmarks != NULL) {
{
//code ommitted
}
// Reset parameters that may be overriddden bwlow
***void (Benchmark::*method)(ThreadState*) = NULL;*** // What does this code line mean? // Benchmark is a class.
bool fresh_db = false;
int num_threads = FLAGS_threads;
if (name == Slice("fillseq")) {
fresh_db = true;
method = &Benchmark::WriteSeq;
}
При необходимости я также могу подробно описать реализацию Benchmark.
Большое спасибо за помощь!
void (Benchmark::*method)(ThreadState*) = NULL;
// What does this code line mean?
// Benchmark is a class.
Выше указатель на функцию-член. Поскольку функции-члены не похожи на обычные функции (их можно вызывать только для допустимого объекта), вы не можете воспринимать их адрес так же, как для свободной функции.
Поэтому приведенный выше синтаксис введен. Это похоже на обычный указатель на функцию, за исключением спецификатора класса Benchmark::
, По сути это тип неявного this
указатель.
В твоем случае, method
это указатель на функцию-член, которая принимает ThreadState*
в качестве параметра, и имеет void
тип возврата. Причиной его использования, скорее всего, является упрощение вызова. Во-первых, и на основе различных параметров выбирается функция-член для вызова, а ее «адрес» сохраняется в method
, После того, как все проверки выполнены, указатель на член выполняет только один вызов выбранной функции.
Между прочим, &Benchmark::WriteSeq
как код получает «адрес» функции-члена WriteSeq
, Вы должны использовать оператор адреса в квалифицированном имени функции.
Других решений пока нет …