Стандартная безопасная проверка типа?

В моем IsSame функция, которую я хотел бы вернуть true если оба указателя указывают на объекты одного и того же тип. Так что только средний звонок должен вернуться true, D1 а также B не должно считаться тем же.

Ниже, кажется, именно то, что я хочу, но безопасно ли в соответствии со стандартом?

#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));
}

Выход:

0 1 0

1

Решение

Вы пытаетесь увидеть, имеют ли два объекта одну и ту же v-таблицу. Стандарт C ++ не говорит о наличии указателя v-таблицы, не говоря уже о том, где он будет в макете объекта. Итак, ваше решение тривиально нестандартно, и поведение вашей программы на самом деле не определено.

Если вы хотите увидеть, имеют ли два базовых указателя одинаковый производный тип, но без RTTI, вам понадобится какой-то механизм, позволяющий узнать идентификатор производного типа. Вероятно, это означает, что виртуальный метод возвращает идентификатор, который должны быть реализованы всеми производными типами.

6

Другие решения

Кажется, работает следующее:

#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;
}

Компилируя с gcc 4.7.2, я получаю следующий вывод:

[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

Помните, что этот код не будет компилироваться, если вы решите компилировать без «информации о типе времени выполнения» (RTTI; -fno-rtti флаг компиляции в gcc).

4

По вопросам рекламы [email protected]