C++ 标准安全类型检查?

C++ 标准安全类型检查?,c++,rtti,C++,Rtti,在我的IsSame函数中,如果两个指针指向相同类型的对象,我想返回true。因此,只有中间调用应该返回trueD1和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)

在我的
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));
}

以下似乎有效:

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

请注意,如果您决定在没有“运行时类型信息”(RTTI;gcc中的
-fno-RTTI
编译标志)的情况下编译,则不会编译此代码

以下方法似乎有效:

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

请注意,如果您决定在没有“运行时类型信息”(RTTI;gcc中的
-fno-RTTI
编译标志)的情况下编译,则不会编译此代码

您正在尝试查看这两个对象是否具有相同的v形表。C++标准不表示V表指针的存在,更不用说它将在对象的布局中。因此,您的解决方案是非常不标准的,并且您的程序的行为实际上是未定义的


如果要查看两个基指针是否具有相同的派生类型但没有RTTI,则需要某种机制来让您知道派生类型的id。这可能意味着一个虚拟方法返回所有派生类型都必须实现的id。

您正在尝试查看这两个对象是否具有相同的v-table。C++标准不表示V表指针的存在,更不用说它将在对象的布局中。因此,您的解决方案是非常不标准的,并且您的程序的行为实际上是未定义的



如果要查看两个基指针是否具有相同的派生类型但没有RTTI,则需要某种机制来让您知道派生类型的id。这可能意味着一个虚拟方法返回一个所有派生类型都必须实现的id。

代码甚至没有意义。为什么要进行差异化?转换为
intptr\u t*
有什么意义?我想您是想看看这两个对象是否指向同一个vtable?这绝对不是标准的。你能不能只使用
std::is_same::value
(其他的也一样)?@acidzombie24:他们都没有注意到你正在尝试进行动态类型查找。这些解决方案只能在编译时使用静态类型。代码甚至没有意义。为什么要进行差异化?转换为
intptr\u t*
有什么意义?我想您是想看看这两个对象是否指向同一个vtable?这绝对不是标准的。你能不能只使用
std::is_same::value
(其他的也一样)?@acidzombie24:他们都没有注意到你正在尝试进行动态类型查找。这些解决方案只能在编译时使用静态类型。您正在使用模板,因此
T1
T2
在编译时匹配,因此
typeid
的用途在这里真的失去了。(这就是为什么我删除了我的答案。)你应该匹配问题,在比较时只有
B*
。@GManNickG,@acidzombie24:恐怕我不明白;((对不起,这里是初学者)。没有模板的版本怎么样?另外,你能详细说明一下为什么
typeid
的用途丢失了吗?@acidzombie24:我删除了我的答案,因为它有与这个答案相同的错误信息。这个答案完全没有抓住要点,因为它直接使用了对象,所以它直接在模板参数中包含类型。我修改了回答:使用动态查找完整演示解决方案。@GManNickG:你的回答很好。我禁用运行时信息时,只是想知道typeid是否有效。你为什么要删除你的答案?哦,对了,我以为你使用的是B*而不是模板。-编辑-该死,我没有在中编辑time@Arrieta:您正在使用
d1
d2
d直接来说,因此类型
D1
D2
在编译时就被直接知道了。那么这里就不需要
typeid
。问题的关键是我们只有
B*
可以使用,并且需要动态地进行类型查找。我犯了同样的错误,别难过。你需要做我的答案所做的事情,然后工作在进行任何进一步的类型检查之前,使用
B*
。您没有模板的版本更符合要点,是的。您使用的模板在编译时与
T1
T2
匹配,因此
typeid
的目的在这里真的丢失了。(这就是我删除答案的原因。)您应该匹配问题,在比较时只有
B*
。@gmannick,@acidzombie24:恐怕我不明白;((对不起,这里是初学者)。没有模板的版本怎么样?另外,你能详细说明一下为什么
typeid
的用途丢失了吗?@acidzombie24:我删除了我的答案,因为它有与这个答案相同的错误信息。这个答案完全没有抓住要点,因为它直接使用了对象,所以它直接在模板参数中包含类型。我修改了回答:使用动态查找完整演示解决方案。@GManNickG:你的回答很好。我禁用运行时信息时,只是想知道typeid是否有效。你为什么要删除你的答案?哦,对了,我以为你使用的是B*而不是模板。-编辑-该死,我没有在中编辑time@Arrieta:您正在使用
d1
d2
d直接来说,因此类型
D1
D2
在编译时就被直接知道了。那么这里就不需要
typeid
。问题的关键是我们只有
B*
可以使用,并且需要动态地进行类型查找。我犯了同样的错误,别难过。你需要做我的答案所做的事情,然后工作在您进行任何进一步的类型检查之前,请使用
B*
。您没有模板的版本更符合这一点,是的。遗憾的是,标准没有指定获取vtable ptr的方法。@acidzombie24,正如用户315052所指出的,重点是标准没有
[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