在我的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
答案 0 :(得分:6)
您正在尝试查看这两个对象是否具有相同的v表。 C ++标准没有说出v表指针的存在,更不用说它在对象布局中的位置了。因此,您的解决方案非常简单,并且程序的行为实际上是未定义的。
如果要查看两个基本指针是否具有相同的派生类型但没有RTTI,则需要一些机制来让您知道派生类型的ID。这可能意味着一个返回所有派生类型必须实现的id的虚方法。
答案 1 :(得分:4)
以下似乎有效:
#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; gcc中的-fno-rtti
编译标志)的情况下进行编译,则此代码将无法编译。