标准安全型检查?

时间:2013-04-25 00:04:44

标签: c++ rtti

在我的IsSame函数中,如果两个指针指向同一类型的对象,我想返回true。所以只有中间调用才能返回trueD1B不应视为相同。

以下似乎正是我想要的,但根据标准是否安全?

#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

2 个答案:

答案 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编译标志)的情况下进行编译,则此代码将无法编译。