In my IsSame function I would like to return true if both pointers are pointing to objects of the same type. So only the middle call should return true. D1 and B shouldn't be considered the same.

The below seems to be exactly what I want but is it safe according to the standard?

#include <stdio.h>

class B { virtual void foo() {} };
class D1 : public B { };
class D2 : public B { };
class D3 : public B { };

bool IsSame(B*a, B*b) {
    if (a == 0 || b == 0)
        return false;
    return *(intptr_t*)a == *(intptr_t*)b;
}

int main() {
    D1 d1;
    D2 d2;
    D1 d1b;
    B b;
    printf("%d %d %d\n", IsSame(&d1, &d2), IsSame(&d1, &d1b), IsSame(&d1, &b));
}

Output:

0 1 0
有帮助吗?

解决方案

You are trying to see if the two objects have the same v-table. The C++ standard does not speak to the presence of a v-table pointer, let alone where it would be in an object's layout. So, your solution is trivially non-standard, and the behavior of your program is in fact undefined.

If you want to see if the two base pointers have the same derived type but without RTTI, you will need some mechanism to let you know the id of a derived type. This likely means a virtual method that returns an id that all the derived types have to implement.

其他提示

The following seems to work:

#include<typeinfo>
#include<iostream>

class B { virtual void foo() {} };
class D1 : public B { };
class D2 : public B { };
class D3 : public B { };


template<typename T1, typename T2>
bool is_same(const T1& t1, const T2& t2) {
  return typeid(t1) == typeid(t2);
}

bool is_same_no_template(const B& b1, const B& b2) {
  return typeid(b1) == typeid(b2);
}

int main(){
    D1 d1;
    D2 d2;
    D1 d1b;
    B b;
    std::cout<<std::boolalpha
             <<"d1 == d2  ? "<<is_same(d1, d2)<<std::endl
             <<"d1 == d1b ? "<<is_same(d1, d1b)<<std::endl
             <<"d1 == b   ? "<<is_same(d1, b)<<std::endl;

    std::cout<<"No Template"<<std::endl;

    std::cout<<std::boolalpha
             <<"d1 == d2  ? "<<is_same_no_template(d1, d2)<<std::endl
             <<"d1 == d1b ? "<<is_same_no_template(d1, d1b)<<std::endl
             <<"d1 == b   ? "<<is_same_no_template(d1, b)<<std::endl;

    return 0;
}

Compiling with gcc 4.7.2 I get the following output:

[Prompt] g++ example.cpp -std=c++11
[Prompt] ./a.out
d1 == d2  ? false
d1 == d1b ? true
d1 == b   ? false
No Template
d1 == d2  ? false
d1 == d1b ? true
d1 == b   ? false

Beware that this code will not compile if you decide to compile without "run-time type information" (RTTI; the -fno-rtti compile flag in gcc).

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top