У меня есть следующий конструктор:
MutexWrapper::MutexWrapper(Mutex * pMutex)
{
DebugPrint("0x%x", pMutex); // displays 0x1f83e54
}
И он вызывается в следующей функции:
void OnReviewBuffer_Callback( void * pUserData )
{
ReviewBuffer * thePointer = (ReviewBuffer *) pUserData;
DebugPrint("0x%x", thePointer); // this displays 0x1f83e48
MutexWrapper theMutexWrapper(thePointer);
}
К сожалению, я не могу дать полное определение ReviewBuffer
— но я надеюсь, что ниже достаточно:
class ReviewBuffer : public StreamConsumer_Base, public Mutex
{
...
};
Проблема в том, что когда я распечатываю thePointer
я получил 0x1f83e48
, но значение, напечатанное внутри конструктора: 0x1f83e54
,
Почему значения указателя отличаются — это как-то связано с передачей по значению, передаваемой в копии указателя?
Твой класс ReviewBuffer
использует множественное наследование:
class ReviewBuffer : public StreamConsumer_Base, public Mutex
{
...
};
Внутренний макет класса (вероятно, *) выглядит так:
Offset 0 class StreamConsumer_Base
... contents of that class (12 bytes including alignment: 0x1f83e54 - 0x1f83e48)
Offset 12 class Mutex
... contents of that class (unknown size)
(*) наверное потому что ничто в стандарте не обязывает это. Это просто обычный способ реализации компиляторами.
Когда вы изначально печатаете thePointer
, это указывает на ReviewBuffer
объект т.е. смещение 0 класса. Но когда вы передаете его в свою функцию, компилятор автоматически корректирует указатель на Mutex
часть ReviewBuffer
, С тех пор Mutex
часть находится со смещением 12, значение указателя не может быть одинаковым (подумайте об этом: если бы оно было одинаковым, оно не указывало бы на Mutex
но либо ReviewBuffer
или StreamConsumer_Base
).
Ваш конструктор не по умолчанию MutexWrapper::MutexWrapper
занимает Mutex*
указатель в качестве аргумента. Ваша функция OnReviewBuffer_Callback
бросает предоставленное void*
указатель на ReviewBuffer*
указатель. Единственный способ передать это ReviewBuffer*
указатель в качестве аргумента MutexWrapper::MutexWrapper(Mutex*)
если ReviewBuffer
является производным классом Mutex
, Если ReviewBuffer
также наследует от других классов, понижая ReviewBuffer*
указатель на Mutex*
Указатель может привести к указателю с адресом, отличным от оригинала. Это именно то, что происходит, основываясь на последних изменениях. ReviewBuffer
использует множественное наследование.
В C ++, как и в Java, указатель передается по значению.
Передача по ссылке является неправильным.
Конечно, указатель указывает на то же адрес переменная, похоже, что все передается по ссылке, но … нет.