-2

Why is this pointer comparison not working?

// in handleSlot()...
void* ptr1 = m_expected; // defined as SimpleBase*
void* ptr2 = sender(); // defined as QObject*
if (ptr1 != ptr2)
    return; // this should not be reached, since the debugger shows ptr1 and ptr2 are the same

The background here is that I have a templated type which inherits from both QObject and T, where T is a subclass of SimpleBase. Since I don't know which template instantiation has triggered the slot, I can't do a dynamic cast here to directly compare pointers of the same type.

I also tried comparing the pointer addresses using reinterpret_cast<uintptr_t>, but when I did that oddly enough they yielded different integers.

I was able to workaround the problem by adding an argument to the signal and slot so that it passes const SimpleBase * i.e. this, and the pointer comparison works that way. But I am curious if there is a way to compare these pointers as they were, using sender() instead of passing the extra argument?

Patrick Parker
  • 4,863
  • 4
  • 19
  • 51
  • 4
    Please provide a full [MCVE] so we can run and reproduce your issue. For all we know, this may not actually be the problem code causing the behavior you think it is. – scohe001 Dec 22 '20 at 21:49
  • 4
    FWIW, the `QObject` part of the class and the `SimpleBase` part of the class will have different addresses, even if the point to the same object. – NathanOliver Dec 22 '20 at 21:51
  • 1
    This is relevant: https://stackoverflow.com/a/42504012/8593689. In short, what @NathanOliver said is correct, the answer I linked goes into detail as to why this is. – Shane Bishop Dec 22 '20 at 21:54
  • 3
    It seems you can `dynamic_cast(sender())` or `dynamic_cast(m_expected)` assuming both are unique and have a `virtual` function. Multi-inherited bases do have different actual addresses and you can’t compare them fir equality using `void*` always. – Dietmar Kühl Dec 22 '20 at 22:00
  • @DietmarKühl - that's the answer. it did not occur to me that I could dynamic cast between two declared types that weren't directly related. but I guess the runtime information allows that to happen. feel free to write up as answer and I'll give you credit – Patrick Parker Dec 22 '20 at 22:35

1 Answers1

1

It seems you can dynamic_cast<SimpleType*>(sender()) or dynamic_cast<QObject*>(m_expected) assuming both are unique and have a virtual function. Multi-inherited bases do have different actual addresses and you can’t compare them for equality using void* always.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • Actually according to this other question https://stackoverflow.com/q/8225501/7098259 using void* to test for object identity is valid in C++, but must be casted via dynamic_cast – Patrick Parker May 28 '22 at 06:36